on 48c88bf help sign in
.bazaar/Makefilenew file+6
since splitsnapshots
unifiedsplit
@@ -0,0 +1,6 @@
1+install:
2+ mkdir -p ~/.bazaar/plugins
3+ cp plugins/* ~/.bazaar/plugins
4+
5+uninstall:
6+ rm ~/.bazaar/plugins/makecheck_unity_phablet.py*
.bazaar/plugins/makecheck_unity_phablet.pynew file+43
@@ -0,0 +1,43 @@
1+#!/usr/bin/python
2+# Copyright 2013 Canonical Ltd.
3+#
4+# This program is free software; you can redistribute it and/or modify
5+# it under the terms of the GNU Lesser General Public License as published by
6+# the Free Software Foundation; version 3.
7+#
8+# This program is distributed in the hope that it will be useful,
9+# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+# GNU Lesser General Public License for more details.
12+#
13+# You should have received a copy of the GNU Lesser General Public License
14+# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
16+import os, subprocess
17+from bzrlib import branch, errors
18+from bzrlib.urlutils import dirname, local_path_from_url
19+
20+def execute_makecheck(local_branch, master_branch, old_revision_number, old_revision_id, future_revision_number, future_revision_id, tree_delta, future_tree):
21+ if not master_branch.basis_tree().has_filename("Shell.qml"):
22+ return
23+
24+ os.chdir(local_path_from_url(master_branch.base))
25+
26+ print "Executing 'make -C builddir test'.."
27+ os.environ['CTEST_OUTPUT_ON_FAILURE'] = "1"
28+ if (subprocess.call("make -C builddir test", shell=True) != 0):
29+
30+ print("\n\n*** Warning ***\n\nBasic tests failed. This commit will not pass continuous integration.")
31+
32+ branch = local_branch or master_branch
33+ revision = branch.repository.get_revision(future_revision_id)
34+ msg_file = open('message.txt', 'w')
35+ msg_file.write(revision.message)
36+ msg_file.close()
37+
38+ print("\n\nSaved commit message to $SRC_DIR/message.txt.")
39+ print("You can uncommit this revision, fix the tests and reuse your message running:\n\nbzr commit -F message.txt\n\n")
40+ elif os.path.isfile("message.txt"):
41+ os.remove("message.txt")
42+
43+branch.Branch.hooks.install_named_hook('pre_commit', execute_makecheck, 'make check pre-commit')
.bzr-builddeb/default.confnew file+2
@@ -0,0 +1,2 @@
1+[BUILDDEB]
2+split = True
.bzrignorenew file+10
@@ -0,0 +1,10 @@
1+# default build dir
2+/builddir
3+# QtCreator project files
4+/*.user
5+# Eclipse project files
6+/.project
7+/.cproject
8+/.settings
9+/.pydevproject
10+message.txt
.crossbuilder/post_deploydeleted−1
@@ -1 +0,0 @@
1−restart unity8
.gitignore−7
@@ -2,15 +2,8 @@
2/builddir
2/builddir
3# QtCreator project files
3# QtCreator project files
4/*.user
4/*.user
5−*.qmlc
6−*.jsc
7# Eclipse project files
5# Eclipse project files
8/.project
6/.project
9/.cproject
7/.cproject
10/.settings
8/.settings
11/.pydevproject
9/.pydevproject
12−# KDevelop project Files
13−/.kdev4/
14−/build/
15−/*.kdev4
16−.clickable/
.projectdeleted−17
@@ -1,17 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<projectDescription>
3− <name>Unity8</name>
4− <comment></comment>
5− <projects>
6− </projects>
7− <buildSpec>
8− <buildCommand>
9− <name>org.python.pydev.PyDevBuilder</name>
10− <arguments>
11− </arguments>
12− </buildCommand>
13− </buildSpec>
14− <natures>
15− <nature>org.python.pydev.pythonNature</nature>
16− </natures>
17−</projectDescription>
.pydevprojectdeleted−10
@@ -1,10 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2−<?eclipse-pydev version="1.0"?><pydev_project>
3−<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
4−<path>/Unity8/tests/autopilot</path>
5−<path>/Unity8/.bazaar</path>
6−<path>/Unity8/tests/whitespace</path>
7−</pydev_pathproperty>
8−<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
9−<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
10−</pydev_project>
.settings/Autopilot List.launchdeleted−14
@@ -1,14 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2−<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
3−<stringAttribute key="bad_container_name" value="/Unity8/.pyd"/>
4−<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"/>
5−<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"/>
6−<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
7−<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
8−</listAttribute>
9−<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/autopilot"/>
10−<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
11−<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="list unity8"/>
12−<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
13−<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Unity8"/>
14−</launchConfiguration>
.settings/Autopilot Run.launchdeleted−14
@@ -1,14 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2−<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
3−<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"/>
4−<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"/>
5−<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
6−<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
7−<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
8−</listAttribute>
9−<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/autopilot"/>
10−<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
11−<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="run ${string_prompt:the test suite to run:unity8}"/>
12−<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
13−<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Unity8"/>
14−</launchConfiguration>
ApplicationArguments.hnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+
20+#ifndef APPLICATION_ARGUMENTS_H
21+#define APPLICATION_ARGUMENTS_H
22+
23+#include <QObject>
24+#include <QSize>
25+#include <QStringList>
26+
27+class ApplicationArguments : public QObject
28+{
29+ Q_OBJECT
30+public:
31+ ApplicationArguments(const QStringList& args) {
32+ if (args.contains(QLatin1String("-geometry")) && args.size() > args.indexOf(QLatin1String("-geometry")) + 1) {
33+ QStringList geometryArg = args.at(args.indexOf(QLatin1String("-geometry")) + 1).split('x');
34+ if (geometryArg.size() == 2) {
35+ m_size.rwidth() = geometryArg.at(0).toInt();
36+ m_size.rheight() = geometryArg.at(1).toInt();
37+ }
38+ }
39+ }
40+
41+ Q_INVOKABLE bool hasGeometry() const { return m_size.isValid(); }
42+ Q_INVOKABLE int width() const { return m_size.width(); }
43+ Q_INVOKABLE int height() const { return m_size.height(); }
44+
45+private:
46+ QSize m_size;
47+};
48+
49+#endif // APPLICATION_ARGUMENTS_H
Applications/Application.qmlnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "applications.js" as ApplicationsModel
19+import Unity.Application 0.1
20+
21+/* This class is temporary. It is meant to be API compatible with qthybris' Application
22+ class.
23+ This class can be removed as soon as qthybris' Application is instantiable from QML
24+ and its 'desktopFile' property becomes writable.
25+ This also requires qthybris to be easily compilable on the desktop.
26+*/
27+QtObject {
28+ id: application
29+
30+ property string desktopFile
31+ property string name
32+ property string comment
33+ property string icon
34+ property string exec
35+ property string stage
36+ property bool fullscreen
37+
38+ onDesktopFileChanged: {
39+ var applicationData = ApplicationsModel.__availableApplications[desktopFile];
40+ if (applicationData) {
41+ application.name = applicationData.name;
42+ application.icon = applicationData.icon;
43+ application.exec = applicationData.exec;
44+ application.stage = applicationData.stage ? applicationData.stage : ApplicationInfo.MainStage;
45+ application.fullscreen = applicationData.fullscreen ? applicationData.fullscreen : false;
46+ } else {
47+ application.name = "";
48+ application.icon = "";
49+ application.exec = "";
50+ application.stage = "";
51+ application.fullscreen = false;
52+ }
53+ }
54+}
Applications/applications.jsnew file+115
@@ -0,0 +1,115 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+// mimic qtubuntu's Application.Stage enum
18+var MainStage = 0;
19+var SideStage = 1;
20+
21+var __availableApplications = {
22+ '/usr/share/applications/phone-app.desktop': {
23+ 'name': i18n.tr("Phone"),
24+ 'icon': 'phone-app',
25+ 'exec': '/usr/bin/phone-app',
26+ 'stage': SideStage
27+ },
28+ '/usr/share/applications/camera-app.desktop': {
29+ 'name': i18n.tr("Camera"),
30+ 'icon': 'camera',
31+ 'fullscreen': true,
32+ 'exec': '/usr/bin/camera-app --fullscreen'
33+ },
34+ '/usr/share/applications/gallery-app.desktop': {
35+ 'name': i18n.tr("Gallery"),
36+ 'icon': 'gallery',
37+ 'exec': '/usr/bin/gallery-app'
38+ },
39+ '/usr/share/applications/facebook-webapp.desktop': {
40+ 'name': i18n.tr("Facebook"),
41+ 'icon': 'facebook',
42+ 'exec': '/usr/bin/webbrowser-app --chromeless http://m.facebook.com',
43+ 'stage': SideStage
44+ },
45+ '/usr/share/applications/webbrowser-app.desktop': {
46+ 'name': i18n.tr("Browser"),
47+ 'icon': 'browser',
48+ 'exec': '/usr/bin/webbrowser-app'
49+ },
50+ '/usr/share/applications/twitter-webapp.desktop': {
51+ 'name': i18n.tr("Twitter"),
52+ 'icon': 'twitter',
53+ 'exec': '/usr/bin/webbrowser-app --chromeless http://www.twitter.com',
54+ 'stage': SideStage
55+ },
56+ '/usr/share/applications/gmail-webapp.desktop': {
57+ 'name': i18n.tr("GMail"),
58+ 'icon': 'gmail',
59+ 'exec': '/usr/bin/webbrowser-app --chromeless http://m.gmail.com'
60+ },
61+ '/usr/share/applications/ubuntu-weather-app.desktop': {
62+ 'name': i18n.tr("Weather"),
63+ 'icon': 'weather',
64+ 'exec': '/usr/bin/qmlscene /usr/share/ubuntu-weather-app/ubuntu-weather-app.qml',
65+ 'stage': SideStage
66+ },
67+ '/usr/share/applications/notes-app.desktop': {
68+ 'name': i18n.tr("Notepad"),
69+ 'icon': 'notepad',
70+ 'exec': '/usr/bin/qmlscene /usr/share/notes-app/NotesApp.qml',
71+ 'stage': SideStage
72+ },
73+ '/usr/share/applications/calendar-app.desktop': {
74+ 'name': i18n.tr("Calendar"),
75+ 'icon': 'calendar',
76+ 'exec': '/usr/bin/qmlscene /usr/share/calendar-app/calendar.qml',
77+ 'stage': SideStage
78+ },
79+ '/usr/share/applications/mediaplayer-app.desktop': {
80+ 'name': i18n.tr("Media Player"),
81+ 'icon': 'mediaplayer-app',
82+ 'fullscreen': true,
83+ 'exec': '/usr/bin/mediaplayer-app'
84+ },
85+ '/usr/share/applications/evernote.desktop': {
86+ 'name': i18n.tr("Evernote"),
87+ 'icon': 'evernote',
88+ 'exec': ''
89+ },
90+ '/usr/share/applications/map.desktop': {
91+ 'name': i18n.tr("Map"),
92+ 'icon': 'map',
93+ 'exec': ''
94+ },
95+ '/usr/share/applications/pinterest.desktop': {
96+ 'name': i18n.tr("Pinterest"),
97+ 'icon': 'pinterest',
98+ 'exec': ''
99+ },
100+ '/usr/share/applications/soundcloud.desktop': {
101+ 'name': i18n.tr("SoundCloud"),
102+ 'icon': 'soundcloud',
103+ 'exec': ''
104+ },
105+ '/usr/share/applications/wikipedia.desktop': {
106+ 'name': i18n.tr("Wikipedia"),
107+ 'icon': 'wikipedia',
108+ 'exec': ''
109+ },
110+ '/usr/share/applications/youtube.desktop': {
111+ 'name': i18n.tr("YouTube"),
112+ 'icon': 'youtube',
113+ 'exec': ''
114+ },
115+}
Bottombar/Bottombar.qmlnew file+227
@@ -0,0 +1,227 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../Components"
19+import "../Components/Math.js" as MathLocal
20+import Unity 0.1
21+import Unity.Application 0.1
22+import Ubuntu.Gestures 0.1
23+
24+Item {
25+ id: bottombar
26+
27+ // Whether there's an application on foreground (as opposed to have shell's Dash on foreground)
28+ property bool applicationIsOnForeground
29+
30+ property variant theHud
31+ property bool enabled: false
32+ property bool preventHiding: dragArea.dragging
33+ readonly property real bottomEdgeButtonCenterDistance: units.gu(34)
34+
35+ state: "hidden"
36+
37+ function hide() {
38+ dismissTimer.stop()
39+ bottombar.state = "hidden"
40+ }
41+
42+ onApplicationIsOnForegroundChanged: {
43+ if (!applicationIsOnForeground) {
44+ hide()
45+ }
46+ }
47+
48+ onStateChanged: {
49+ if (state == "hidden") {
50+ dismissTimer.stop()
51+ bottomBarVisibilityCommunicatorShell.forceHidden = false
52+ } else {
53+ dismissTimer.restart()
54+ }
55+ }
56+
57+ onPreventHidingChanged: {
58+ if (!preventHiding) {
59+ if (state == "hint" || state == "reveal")
60+ hide()
61+ }
62+
63+ if (dismissTimer.running) {
64+ dismissTimer.restart();
65+ }
66+ }
67+
68+ Timer {
69+ id: dismissTimer
70+ interval: 1000
71+ onTriggered: {
72+ if (!bottombar.preventHiding) {
73+ bottombar.state = "hidden"
74+ } else {
75+ dismissTimer.restart()
76+ }
77+ }
78+ }
79+
80+ HudButton {
81+ id: hudButton
82+
83+ readonly property bool centeredHud: parent.width < units.gu(68) // Nexus 7 has 67 gu width
84+
85+ x: centeredHud ? parent.width / 2 - width / 2 : MathLocal.clamp(dragArea.touchStartX - (width / 2), 0, bottombar.width - width)
86+ y: bottombar.height - bottomEdgeButtonCenterDistance - (height / 2) - bottomMargin
87+ z: 1
88+ visible: opacity != 0
89+
90+ mouseOver: {
91+ if (dragArea.status === DirectionalDragArea.Recognized) {
92+ var touchLocal = mapFromItem(dragArea, dragArea.touchX, dragArea.touchY)
93+ return touchLocal.x > 0 && touchLocal.x < width
94+ && touchLocal.y > 0 && touchLocal.y < height
95+ } else {
96+ return false
97+ }
98+ }
99+
100+ onClicked: theHud.show()
101+
102+ Behavior on bottomMargin {
103+ NumberAnimation{duration: hudButton.opacity < 0.01 ? 200 : 70; easing.type: Easing.OutQuart}
104+ }
105+
106+ Behavior on opacity {
107+ NumberAnimation{duration: 200; easing.type: Easing.OutCubic}
108+ }
109+ }
110+
111+ Connections {
112+ target: theHud
113+ onShownChanged: {
114+ bottomBarVisibilityCommunicatorShell.forceHidden = theHud.shown
115+ if (theHud.shown) {
116+ bottombar.state = "hidden"
117+ }
118+ }
119+ }
120+
121+ EdgeDragArea {
122+ id: dragArea
123+ objectName: "hudDragArea"
124+ width: parent.width
125+ height: shell.edgeSize
126+ anchors.bottom: parent.bottom
127+
128+ distanceThreshold: units.gu(8)
129+ enabled: !theHud.shown && bottombar.enabled && applicationIsOnForeground
130+ direction: Direction.Upwards
131+ maxSilenceTime: 2000
132+
133+ property int previousStatus: -1
134+ property real touchStartX: -1
135+
136+ readonly property real distanceFromThreshold: (-distance) - distanceThreshold // distance is negative
137+ readonly property real revealDistance: units.gu(2)
138+ readonly property real commitDistance: units.gu(6)
139+ readonly property real commitProgress: MathLocal.clamp(distanceFromThreshold / commitDistance, 0, 1)
140+
141+ onStatusChanged: {
142+ if (status === DirectionalDragArea.WaitingForTouch) {
143+ if (previousStatus == DirectionalDragArea.Recognized) {
144+ if (hudButton.mouseOver) {
145+ hudButton.clicked()
146+ }
147+ }
148+ } else if (status === DirectionalDragArea.Undecided) {
149+ if (!hudButton.centeredHud) {
150+ touchStartX = touchX
151+ }
152+ } else if (status === DirectionalDragArea.Recognized) {
153+ bottombar.state = "hint"
154+ }
155+ previousStatus = status
156+ }
157+
158+ onDistanceChanged: {
159+ if (status === DirectionalDragArea.Recognized) {
160+ if (distanceFromThreshold > commitDistance)
161+ bottombar.state = "shown"
162+ else if (distanceFromThreshold > revealDistance)
163+ bottombar.state = "reveal"
164+ }
165+ }
166+ }
167+
168+ Item {
169+ id: dismissArea
170+ anchors {
171+ top: parent.top
172+ left: parent.left
173+ right: parent.right
174+ }
175+ height: parent.height - bottomBarVisibilityCommunicatorShell.position
176+
177+ MouseArea {
178+ anchors.fill: parent
179+ enabled: bottombar.state == "shown"
180+ onPressed: {
181+ bottomBarVisibilityCommunicatorShell.forceHidden = true
182+ bottombar.state = "hidden"
183+ }
184+ }
185+
186+ InputFilterArea {
187+ anchors.fill: parent
188+ blockInput: (hudButton.opacity == 1)
189+ }
190+ }
191+
192+ MouseArea {
193+ anchors {
194+ top: dismissArea.bottom
195+ left: parent.left
196+ right: parent.right
197+ bottom: parent.bottom
198+ }
199+ enabled: bottombar.state == "shown" && bottomBarVisibilityCommunicatorShell.position > 0
200+ onPressed: {
201+ bottombar.state = "hidden"
202+ }
203+ }
204+
205+ states: [
206+ State {
207+ name: "hidden"
208+ PropertyChanges { target: hudButton; opacity: 0 }
209+ PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) }
210+ },
211+ State {
212+ name: "hint"
213+ extend: "hidden"
214+ PropertyChanges { target: hudButton; opacity: 0.5 }
215+ },
216+ State {
217+ name: "reveal"
218+ extend: "hint"
219+ PropertyChanges { target: hudButton; bottomMargin: units.gu(-2) + units.gu(2) * dragArea.commitProgress }
220+ },
221+ State {
222+ name: "shown"
223+ PropertyChanges { target: hudButton; opacity: 1 }
224+ PropertyChanges { target: hudButton; bottomMargin: units.gu(0) }
225+ }
226+ ]
227+}
Bottombar/HudButton.qmlnew file+64
@@ -0,0 +1,64 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: item
22+
23+ property bool mouseOver
24+
25+ property int bottomMargin: units.gu(2)
26+
27+ signal clicked()
28+
29+ readonly property real scaleOnMouseOver: 1.2
30+
31+ width: hudButton.width * scaleOnMouseOver
32+ height: hudButton.height * scaleOnMouseOver
33+
34+ Item {
35+ id: hudButton
36+
37+ anchors.centerIn: parent
38+ height: units.gu(12)
39+ width: height
40+ opacity: item.mouseOver || abstractButton.pressed ? 1 : 0.7
41+ scale: item.mouseOver || abstractButton.pressed ? scaleOnMouseOver : 1
42+ Behavior on opacity {NumberAnimation{duration: 200; easing.type: Easing.OutQuart}}
43+ Behavior on scale {NumberAnimation{duration: 200; easing.type: Easing.OutQuart}}
44+
45+ AbstractButton {
46+ id: abstractButton
47+ anchors.fill: parent
48+ style: Image {
49+ anchors.fill: parent
50+ source: "graphics/hud_invoke_button_active.png"
51+ }
52+
53+ onClicked: item.clicked()
54+ }
55+
56+ Image {
57+ width: units.gu(4)
58+ height: width
59+ source: "graphics/hud.png"
60+ anchors.centerIn: parent
61+ fillMode: Image.PreserveAspectFit
62+ }
63+ }
64+}
Bottombar/graphics/hud@20.pngnew file

Binary file not shown.

Bottombar/graphics/hud_invoke_button_active@20.pngnew file

Binary file not shown.

CMakeLists.txt+77−112
@@ -13,9 +13,8 @@ endif()
13
13
14set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
14set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
15
15
16−# Instruct CMake to run moc and rcc automatically when needed.
16+# Instruct CMake to run moc automatically when needed.
17set(CMAKE_AUTOMOC ON)
17set(CMAKE_AUTOMOC ON)
18−set(CMAKE_AUTORCC ON)
19
18
20# enable QML debugging
19# enable QML debugging
21string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) # Build types should always be lowercase but sometimes they are not.
20string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) # Build types should always be lowercase but sometimes they are not.
@@ -40,19 +39,6 @@ if(cmake_build_type_lower MATCHES coverage)
40 ENABLE_COVERAGE_REPORT(TARGETS ${SHELL_APP} FILTER /usr/include ${CMAKE_SOURCE_DIR}/tests/* ${CMAKE_BINARY_DIR}/*)
39 ENABLE_COVERAGE_REPORT(TARGETS ${SHELL_APP} FILTER /usr/include ${CMAKE_SOURCE_DIR}/tests/* ${CMAKE_BINARY_DIR}/*)
41endif()
40endif()
42
41
43−find_package (ECM 1.7.0 QUIET NO_MODULE)
44−if (ECM_FOUND)
45− # Provides us with -DECM_ENABLE_SANITIZERS='X'
46− # Where X can be address, thread, memory, leak, undefined
47− include("${ECM_MODULE_DIR}/ECMEnableSanitizers.cmake")
48−endif()
49−
50−if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
51− if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0")
52− set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override" )
53− endif()
54−endif()
55−
56# Make sure we have all the needed symbols
42# Make sure we have all the needed symbols
57set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
43set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
58set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,defs")
44set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,defs")
@@ -62,41 +48,11 @@ add_custom_target(cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2
62 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
48 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
63
49
64include(FindPkgConfig)
50include(FindPkgConfig)
65−find_package(Qt5Core 5.6 REQUIRED)
51+find_package(Qt5Core)
66−find_package(Qt5Qml 5.6 REQUIRED)
52+find_package(Qt5Qml)
67−find_package(Qt5Quick 5.6 REQUIRED)
53+find_package(Qt5Quick)
68−find_package(Qt5Gui 5.6 REQUIRED)
54+find_package(Qt5Gui)
69−find_package(Qt5DBus 5.6 REQUIRED)
55+find_package(Qt5DBus)
70−find_package(Qt5Concurrent 5.6 REQUIRED)
71−find_package(Qt5Sql 5.6 REQUIRED)
72−find_package(Qt5Test 5.6 REQUIRED)
73−find_package(Qt5Svg 5.6 REQUIRED)
74−find_package(Qt5Network 5.6 REQUIRED)
75−find_package(Qt5Xml 5.6 REQUIRED)
76−
77−pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=27)
78−pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
79−pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
80−pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
81−pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=13)
82−pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
83−pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
84−pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2)
85−pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
86−pkg_check_modules(QTDBUSTEST REQUIRED
87− libqtdbustest-1
88− libqtdbusmock-1
89− )
90−
91−### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
92−find_path(UBUNTUGESTUREPRIV
93− NAMES UbuntuGestures/private/damper_p.h UbuntuGestures/private/ucswipearea_p.h UbuntuGestures/private/ucswipearea_p_p.h
94− PATHS ${UBUNTUGESTURES_INCLUDEDIR}/UbuntuGestures/${UBUNTUGESTURES_VERSION}
95− NO_DEFAULT_PATH)
96−if (${UBUNTUGESTUREPRIV} STREQUAL UBUNTUGESTUREPRIV-NOTFOUND)
97− message(FATAL_ERROR "UbuntuGestures private headers not found.")
98−endif()
99−# end of UbuntuGesture private headers check
100
56
101# Standard install paths
57# Standard install paths
102include(GNUInstallDirs)
58include(GNUInstallDirs)
@@ -104,22 +60,18 @@ include(GNUInstallDirs)
104set(SHELL_APP_DIR ${CMAKE_INSTALL_DATADIR}/unity8)
60set(SHELL_APP_DIR ${CMAKE_INSTALL_DATADIR}/unity8)
105set(SHELL_PRIVATE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/unity8)
61set(SHELL_PRIVATE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/unity8)
106
62
107−execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugin_private_module_dir SystemSettings OUTPUT_VARIABLE USS_PRIVATE_PLUGINDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
63+configure_file(paths.h.in ${CMAKE_CURRENT_BINARY_DIR}/paths.h @ONLY)
108−if(USS_PRIVATE_PLUGINDIR STREQUAL "")
109− message(FATAL_ERROR "Could not determine USS private plugin installation dir.")
110−endif()
111
64
112−execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugindir_suffix unity-shell-api OUTPUT_VARIABLE SHELL_INSTALL_QML OUTPUT_STRIP_TRAILING_WHITESPACE)
65+pkg_check_modules(UNITY-MIR REQUIRED unity-mir)
113−if(SHELL_INSTALL_QML STREQUAL "")
114− message(FATAL_ERROR "Could not determine plugin installation dir.")
115−endif()
116
66
117−set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
67+include_directories(
68+ ${CMAKE_CURRENT_BINARY_DIR}
69+ ${CMAKE_CURRENT_SOURCE_DIR}
70+ ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
71+ ${UNITY-MIR_INCLUDE_DIRS}
72+ )
118
73
119−execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=plugindir unity-shell-api OUTPUT_VARIABLE SHELL_PLUGINDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
74+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
120−if(SHELL_PLUGINDIR STREQUAL "")
121− message(FATAL_ERROR "Could not determine plugin import dir.")
122−endif()
123
75
124set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra")
76set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra")
125
77
@@ -137,72 +89,85 @@ endif()
137# "signals" and "slots"
89# "signals" and "slots"
138add_definitions(-DQT_NO_KEYWORDS)
90add_definitions(-DQT_NO_KEYWORDS)
139
91
140−# Save a few container detach and conversions
92+# Tests
141−add_definitions(-DQT_STRICT_ITERATORS)
93+include(CTest)
142−
94+enable_testing()
143−# Use the fast string builder
144−add_definitions(-DQT_USE_QSTRINGBUILDER)
145
95
146# Autopilot tests
96# Autopilot tests
147include(autopilot)
97include(autopilot)
148declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
98declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
149
99
150set(SHELL_APP unity8)
100set(SHELL_APP unity8)
151−set(INDICATORS_CLIENT_APP indicators-client)
152−set(GREETER_APP unity8-greeter)
153−set(MOCK_INDICATOR_SERVICE_APP unity-mock-indicator-service)
154
101
155−include_directories(
102+set(shell_app_HDRS
156− ${CMAKE_SOURCE_DIR}/include
103+ )
157− ${CMAKE_BINARY_DIR}/include
158− ${APPLICATION_API_INCLUDE_DIRS}
159−)
160−
161−# Quiet logger
162−set(QUIET_LOGGER OFF CACHE BOOL "Disable test output on stdout.")
163−if(NOT QUIET_LOGGER)
164− set(STDOUT_LOGGER "-o" "-,txt")
165−endif()
166
104
167−execute_process(COMMAND dpkg-architecture -qDEB_HOST_ARCH OUTPUT_VARIABLE ARCH)
105+add_executable(${SHELL_APP}
168−if (NOT ARCH MATCHES "arm*")
106+ ${shellapplication_MOC_SRCS}
169− set(ENABLE_TOUCH_EMULATION true)
107+ ApplicationArguments.h
170− add_definitions(-DUNITY8_ENABLE_TOUCH_EMULATION)
108+ main.cpp
109+ MouseTouchAdaptor.cpp
110+ )
111+
112+qt5_use_modules(${SHELL_APP} Qml Quick Test)
171− pkg_check_modules(MOUSETOUCHADAPTOR_LIBS REQUIRED x11 xcb xi)
113+pkg_check_modules(XCB REQUIRED xcb)
172−else()
114+
173− set(ENABLE_TOUCH_EMULATION false)
115+if (NOT "${XCB_INCLUDE_DIRS}" STREQUAL "")
174− message(STATUS "Touch emulation support disabled.")
116+ set_target_properties(${SHELL_APP} PROPERTIES INCLUDE_DIRECTORIES ${XCB_INCLUDE_DIRS})
175endif()
117endif()
176
118
119+target_link_libraries(${SHELL_APP}
120+ ${Qt5Qml_LIBRARIES}
121+ ${Qt5Quick_LIBRARIES}
122+ ${XCB_LDFLAGS}
123+ ${CMAKE_DL_LIBS}
124+ )
125+
126+# install binaries
127+install(TARGETS ${SHELL_APP}
128+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
129+ )
130+
131+# install top level qml and js files
132+file(GLOB QML_JS_FILES *.qml *.js)
133+
134+install(FILES ${QML_JS_FILES}
135+ DESTINATION ${SHELL_APP_DIR}
136+ )
137+
177# add subdirectories to build
138# add subdirectories to build
178−add_subdirectory(include)
139+add_subdirectory(tests)
140+add_subdirectory(plugins)
179add_subdirectory(src)
141add_subdirectory(src)
180−add_subdirectory(tools)
181−add_subdirectory(qml)
182
142
183−# Tests
143+# install subdirectories
184−set(NO_TESTS OFF CACHE BOOL "Disable tests.")
144+set(QML_DIRS
185−if (NOT NO_TESTS)
145+ Applications
186− include(CTest)
146+ Bottombar
187− enable_testing()
147+ Components
188− add_subdirectory(tests)
148+ Dash
189−else()
149+ graphics
190− message(STATUS "Tests disabled")
150+ Greeter
191−endif()
151+ Hud
152+ Panel
153+ Launcher
154+ SideStage
155+ Notifications
156+ )
192
157
193−add_subdirectory(plugins)
158+install(DIRECTORY ${QML_DIRS}
159+ DESTINATION ${SHELL_APP_DIR}
160+ )
194
161
195−#
162+# generate desktop file
196−# Data files
163+configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
197−#
164+
198−add_subdirectory(data)
165+# install desktop file
166+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
167+ DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
168+ )
199
169
200#
170#
201# Translation
171# Translation
202#
172#
203add_subdirectory(po)
173add_subdirectory(po)
204−
205−#
206−# Documentation
207−#
208−add_subdirectory(doc)
CODING+60−119
@@ -1,7 +1,7 @@
1Building Unity 8
1Building Unity 8
2================
2================
3
3
4−Only Ubuntu 14.04 (trusty) is supported as a developement environment.
4+Only Ubuntu 13.10 (saucy) is supported as a developement environment.
5
5
6download source
6download source
7---------------
7---------------
@@ -15,17 +15,23 @@ download source
15 $ bzr branch lp:unity8 ~/unity8/trunk
15 $ bzr branch lp:unity8 ~/unity8/trunk
16 $ cd ~/unity8/trunk
16 $ cd ~/unity8/trunk
17
17
18−install dependencies and build Unity 8
18+install dependencies
19--------------------
19--------------------
20+If its your first time, install build dependencies
20
21
21$ cd ~/unity8/trunk
22$ cd ~/unity8/trunk
22−$ ./build.sh
23+$ ./build --setup
23
24
25+ this will:
24− If its your first time, this will install the required dependencies to build and
26+ - install the required dependencies to build, as well as run on the desktop
27+ - it should also install unity-scope-home and unity-lens-application which
28+ are technically "recommends", not strict dependencies
29+
25− build it.
30+build Unity 8
31+-------------
26
32
27− You might want to also install unity-scope-home and unity-scope-click which
33+$ cd ~/unity8/trunk
28− are technically "recommends", not strict dependencies
34+$ ./build
29
35
30You may also rebuild with the -c for clean, which just deletes the build
36You may also rebuild with the -c for clean, which just deletes the build
31directory.
37directory.
@@ -37,21 +43,17 @@ Running Unity 8 on your desktop
37run the Unity 8 shell
43run the Unity 8 shell
38---------------------
44---------------------
39$ cd ~/unity8/trunk
45$ cd ~/unity8/trunk
40−$ cd builddir
46+$ ./run
41
47
42−Each component of unity8 can be ran independently for development and testing
48+Options can be passed to test the lock screen
43−For example:
49+$ ./run -p OR -k
44−$ make tryShell
45−$ make tryLauncher
46−$ make tryLockscreen
47
50
48−Check out the tests/qmltests/ directory for a list of things that can be ran.
51+-p is for pin lock, for which the default prompt answer is "1234"
52+-k is for keylock passphrase, for which the default prompt answer is "password"
49
53
50Notes
54Notes
51-----
55-----
52- to navigate, utilize the mouse left button as you would your finger
56- to navigate, utilize the mouse left button as you would your finger
53−- a three point drag (for side stage operations) can be performed by using
54− the Shift+Control+Alt (all together) keyboard modifiers while using the mouse.
55- to get the translations work, currently you have to do make install to
57- to get the translations work, currently you have to do make install to
56 put the *.mo files into correct structure. We'll look for a better solution
58 put the *.mo files into correct structure. We'll look for a better solution
57 later.
59 later.
@@ -66,15 +68,50 @@ Notes
66
68
67Running Unity 8 on devices
69Running Unity 8 on devices
68==========================
70==========================
71+- Ubuntu Touch builds are currently only available in 13.10 flavour
72+- supported hardware should match one of those listed here
73+ https://wiki.ubuntu.com/Touch/Devices#Running_fine
74+- follow the Ubuntu Touch install instructions for your chosen device
75+ https://wiki.ubuntu.com/Touch/Install
76+- make sure your device is connected to a network
77+- also make sure you have your SSH key in ~/.ssh/id_rsa.pub (or install one
78+ on the device yourself)
79+
80+$ cd ~/unity/trunk
81+$ ./run_on_device --setup
82+ this will:
83+ - install your public SSH key on the device
84+ - install the needed dependencies
69
85
70−Running unity8 on a device should be done using crossbuilder.
86+$ ./run_on_device
71−Go to
87+ this will:
72−* https://launchpad.net/crossbuilder and
88+ - rsync the code to the device
73−* https://wiki.ubuntu.com/Touch/Crossbuilder
89+ - build on the device
74−for more details on crossbuilder.
90+ - replace the running shell
91+
92+Options can be passed to test the lock screen
93+$ ./run_on_device -p OR -k
94+
95+-p is for pin lock, for which the default prompt answer is "1234"
96+-k is for keylock passphrase, for which the default prompt answer is "password"
97+
98+Notes
99+-----
100+- using adb over TCP has some advantages, Google will be of help here
101+ - NOTE: this is not yet available for flipped images
102+ - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
103+ - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
104+ - it's unsafe - anyone can connect to your device
105+ - with TCP the Nexus 10 doesn't drop the adb connection when locking
106+ the screen
107+- exporting ANDROID_SERIAL=$your_device_serial or
108+ ANDROID_SERIAL=$your_device_ip:5555 will make adb not complain about
109+ multiple devices
110+- you can export TARGET_IP=$your_device_ip TARGET_SSH_PORT=22 for run_on_device
111+ to not use adb forwarding - useful if you use multiple devices
112+- using Ninja (package ninja-build - run_on_device -s installs this now)
113+ will improve build times (especially in the nothing-to-build case)
75
114
76−unity8 will automatically restart on the phone once deployment
77−has finished due to post-build-steps set up in this repository.
78
115
79Coding guidelines
116Coding guidelines
80=================
117=================
@@ -90,99 +127,3 @@ Unity 8.
90If using VIM, make sure you install some syntax highlighting for QML, like
127If using VIM, make sure you install some syntax highlighting for QML, like
91https://github.com/peterhoeg/vim-qml
128https://github.com/peterhoeg/vim-qml
92
129
93−Running tests
94−=============
95−
96−Tests are run from the build directory (which will be ./builddir if you used
97−the ./build.sh script).
98−
99−To run the tests that do not require any graphical capability and therefore
100−are pretty fast run:
101−
102−$ make test
103−
104−or, alternatively:
105−
106−$ ctest
107−
108−To run all graphical tests, which can take a couple of minutes:
109−
110−$ make uitests
111−
112−To run the tests for a single component/class:
113−
114−$ make testComponentName
115−
116−So, for the DragHandle component that would be:
117−
118−$ make testDragHandle
119−
120−To run the tests for a single component/class under gdb (so you can catch SEGFAULTS)
121−
122−$ make gdbtestComponentName
123−
124−To run a single test function of a single component/class:
125−
126−$ make testComponentName FUNCTION="TestCaseName::functionName"
127−
128−To run a test application that allow you to manually test or to simply try out
129−a given component:
130−
131−$ make tryComponentName
132−
133−So to try out, for instance, the DragHandle component, you would do:
134−
135−$ make tryDragHandle
136−
137−NB: Manual test or interation doesn't make sense for all components or classes,
138−particularly the non-graphical ones. In such cases no "tryFoo" make target is
139−provided.
140−
141−Running autopilot tests
142−=======================
143−
144−Autopilot tests are run from the build directory (which will be ./builddir if you used
145−the ./build.sh script).
146−
147−$ make autopilot
148−
149−If you want you can also run tests individually, for that you need to install first,
150−otherwise the tests will run on the system-installed version
151−
152−$ make install
153−
154−To see the list of existing autopilot tests you can do
155−
156−$ PYTHONPATH=../tests/autopilot autopilot3 list unity8
157−
158−And then run a single test with
159−
160−$ PYTHONPATH=../tests/autopilot autopilot3 run unity8.some.very.long.test.name
161−
162−or run them all with
163−
164−$ PYTHONPATH=../tests/autopilot autopilot3 run unity8
165−
166−Debugging techniques
167−====================
168−
169−Unity8 heavily uses Qt and with that Qt debugging techniques mostly apply in the
170−same fashion. There are, however, some additional unity8-specific notes:
171−
172−* Enable/disable Qt scenegraph visualizer on the fly:
173−
174− $ qdbus com.canonical.Unity8.Debugging /com/canonical/Unity8/Debugging SetSceneGraphVisualizer <mode>
175−
176− This is equivalent to exporting QSG_VISUALIZE=<mode> before running unity8, except it does it on the
177− fly.
178−
179−* Toggle slow animations on the fly:
180−
181− $ qdbus com.canonical.Unity8.Debugging /com/canonical/Unity8/Debugging SetSlowAnimations <true|false>
182−
183−* Change logging filter rules on the fly:
184−
185− $ qdbus com.canonical.Unity8.Debugging /com/canonical/Unity8/Debugging SetLoggingFilterRules <filter>
186−
187− This is equivalent to exporting QT_LOGGING_RULES or defining them in QT_LOGGING_CONF, except it does
188− it on the fly.
Components/AnimationControllerWithSignals.qmlnew file+64
@@ -0,0 +1,64 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+AnimationController {
20+ signal animationCompletedAtBeginning()
21+ signal animationCompletedAtEnd()
22+ readonly property bool completed: progress == 1.0 || progress == 0.0
23+ property bool completing: false
24+
25+ function __completeAtBeginning() {
26+ completing = false;
27+ animationCompletedAtBeginning();
28+ }
29+
30+ function __completeAtEnd() {
31+ completing = false;
32+ animationCompletedAtEnd();
33+ }
34+
35+ function completeToBeginningWithSignal() {
36+ if (progress == 0.0) {
37+ __completeAtBeginning()
38+ } else {
39+ completing = true;
40+ completeToBeginning();
41+ }
42+ }
43+
44+ function completeToEndWithSignal() {
45+ if (progress == 1.0) {
46+ __completeAtEnd()
47+ } else {
48+ completing = true;
49+ completeToEnd();
50+ }
51+ }
52+
53+ onProgressChanged: {
54+ if (!completing) {
55+ return;
56+ }
57+
58+ if (progress == 0.0) {
59+ __completeAtBeginning()
60+ } else if (progress == 1.0) {
61+ __completeAtEnd()
62+ }
63+ }
64+}
Components/ApplicationManagerWrapper.qmlnew file+169
@@ -0,0 +1,169 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Unity.Application 0.1
19+
20+Item {
21+ id: root
22+
23+ property alias mainStageApplications: mainStageModel
24+ property alias sideStageApplications: sideStageModel
25+ property variant mainStageFocusedApplication: null
26+ property variant sideStageFocusedApplication: null
27+ property bool sideStageEnabled: true
28+ property bool keyboardVisible: ApplicationManager.keyboardVisible
29+ property int keyboardHeight: ApplicationManager.keyboardHeight
30+
31+ property bool fake: ApplicationManager.fake ? ApplicationManager.fake : false
32+
33+ signal focusRequested(string appId)
34+
35+ ApplicationsModelStageFiltered {
36+ id: mainStageModel
37+ stage: ApplicationInfo.MainStage
38+ }
39+
40+ ApplicationsModelStageFiltered {
41+ id: sideStageModel
42+ stage: ApplicationInfo.SideStage
43+ }
44+
45+ Connections {
46+ target: ApplicationManager
47+ onFocusedApplicationIdChanged: {
48+ var app = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
49+ if (!app) { //nothing at all focused, so clear all
50+ mainStageFocusedApplication = null;
51+ sideStageFocusedApplication = null;
52+ } else {
53+ if (app.stage == ApplicationInfo.MainStage) {
54+ mainStageFocusedApplication = app;
55+ // possible the side stage app being unfocused fired this signal, so check for it
56+ if (sideStageFocusedApplication && !sideStageFocusedApplication.focused)
57+ sideStageFocusedApplication = null;
58+ } else {
59+ sideStageFocusedApplication = app;
60+ // possible the main stage app being unfocused fired this signal, so check for it
61+ if (mainStageFocusedApplication && !mainStageFocusedApplication.focused)
62+ mainStageFocusedApplication = null;
63+ }
64+ }
65+ }
66+
67+ onFocusRequested: {
68+ // if no side stage enabled, override application's stage parameter
69+ var app = ApplicationManager.findApplication(appId);
70+ if (app && app.stage === ApplicationInfo.SideStage && !sideStageEnabled) {
71+ app.stage = ApplicationInfo.MainStage;
72+ }
73+
74+ root.focusRequested(appId);
75+ }
76+ }
77+
78+ function activateApplication(desktopFile, argument) {
79+ var appId;
80+
81+ // HACK: Applications identified sometimes with with appId, but mostly with desktopFile.
82+ // TODO: convert entire shell to use appId only.
83+ if (desktopFile.indexOf(".desktop") >= 0) {
84+ appId = desktopFileToAppId(desktopFile);
85+ } else {
86+ appId = desktopFile;
87+ }
88+
89+ var application = ApplicationManager.findApplication(appId);
90+ if (application !== null) {
91+ return application;
92+ }
93+
94+ var execFlags = sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
95+
96+ if (argument) {
97+ return ApplicationManager.startApplication(appId, execFlags, [argument]);
98+ } else {
99+ return ApplicationManager.startApplication(appId, execFlags);
100+ }
101+ }
102+
103+ function stopApplication(application) {
104+ var appId;
105+
106+ // HACK: Applications identified sometimes with with appId, but mostly with desktopFile.
107+ // TODO: convert entire shell to use appId only.
108+ if (typeof application == "string") {
109+ appId = application;
110+ } else {
111+ appId = desktopFileToAppId(application.desktopFile);
112+ }
113+
114+ ApplicationManager.stopApplication(appId);
115+ }
116+
117+ function focusApplication(application) {
118+ if (application == null || application == undefined) {
119+ return;
120+ }
121+
122+ ApplicationManager.focusApplication(application.appId);
123+ }
124+
125+ function unfocusCurrentApplication() {
126+ ApplicationManager.unfocusCurrentApplication();
127+ }
128+
129+ function moveRunningApplicationStackPosition(from, to, stage) {
130+ if (from == to || from < 0 || to < 0) return;
131+
132+ if (stage == ApplicationInfo.SideStage) {
133+ sideStageModel.move(from, to);
134+ } else {
135+ mainStageModel.move(from, to);
136+ }
137+ }
138+
139+ function getApplicationFromDesktopFile(desktopFile, stage) {
140+ var appId;
141+
142+ // HACK: Applications identified sometimes with with appId, but mostly with desktopFile.
143+ // TODO: convert entire shell to use appId only.
144+ if (desktopFile.indexOf(".desktop") >= 0) {
145+ appId = desktopFileToAppId(desktopFile);
146+ } else {
147+ appId = desktopFile;
148+ }
149+
150+ for (var i = 0, len = ApplicationManager.count; i < len; i++ ) {
151+ var app = ApplicationManager.get(i);
152+
153+ // if stage not specified, return whichever app running on either stage
154+ if (app.appId == appId && (stage == undefined || app.stage == stage)) {
155+ return app;
156+ }
157+ }
158+ }
159+
160+ function desktopFileToAppId(desktopFile) {
161+ var right = desktopFile.lastIndexOf(".desktop");
162+ var left = desktopFile.lastIndexOf("/");
163+ if (left == -1 || right == -1 || left == right) {
164+ console.log("ApplicationManagerWrapper: unable to extract appId from '" + desktopFile + "'");
165+ return "";
166+ }
167+ return desktopFile.substring(left+1, right);
168+ }
169+}
Components/ApplicationScreenshot.qmlnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity.Application 0.1
20+
21+Item {
22+ id: applicationScreenshot
23+
24+ property var application: null
25+ property bool withBackground: false
26+ property bool ready: applicationImage.ready || withBackground
27+
28+ function setApplication(application) {
29+ applicationScreenshot.application = application
30+ }
31+
32+ function clearApplication() {
33+ applicationScreenshot.withBackground = false;
34+ applicationScreenshot.application = null
35+ applicationScreenshot.scheduleUpdate();
36+ }
37+
38+ function scheduleUpdate() {
39+ applicationImage.scheduleUpdate()
40+ }
41+
42+ function updateFromCache() {
43+ applicationImage.updateFromCache()
44+ }
45+
46+ Rectangle {
47+ id: background
48+ anchors.fill: parent
49+ color: "white" // FIXME should use normal background color of Suru theme
50+ visible: applicationScreenshot.withBackground
51+ }
52+
53+ ApplicationImage {
54+ id: applicationImage
55+ objectName: "screenshot image"
56+ width: applicationScreenshot.application ? parent.width : 0
57+ height: applicationScreenshot.application ? parent.height : 0
58+ visible: applicationScreenshot.application != null && ready
59+ source: ApplicationManager.findApplication((application) ? application.appId : "")
60+ }
61+}
Components/ApplicationsModelStageFiltered.qmlnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Utils 0.1
19+import Unity.Application 0.1
20+
21+SortFilterProxyModel {
22+ id: root
23+ property int stage
24+
25+ function get(index) {
26+ return model.get(mapRowToSource(index));
27+ }
28+
29+ function move(from, to) {
30+ var realFrom = mapRowToSource(from);
31+ if (realFrom == -1) {
32+ console.log("ERROR; invalid from=" + from + " index in move operation");
33+ return;
34+ }
35+ var realTo = mapRowToSource(to);
36+ if (realTo == -1) {
37+ // assuming wanting to move to end of list
38+ realTo = model.count - 1;
39+ }
40+
41+ if (realFrom == realTo) return;
42+ model.move(realFrom, realTo);
43+ }
44+
45+ model: ApplicationManager
46+ dynamicSortFilter: true
47+ filterRole: ApplicationManager.RoleStage
48+ filterRegExp: RegExp(stage)
49+}
tests/plugins/Ubuntu/Gestures/empty.qml → Components/BaseCarouselDelegate.qmlrenamed+5−4
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,10 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Gestures 0.1
18+import Ubuntu.Components 0.1
19
19
20Item {
20Item {
21− width: 720; height: 720
21+ property bool explicitlyScaled
22+ property var model
22}
23}
Components/Carousel.qmlnew file+342
@@ -0,0 +1,342 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "carousel.js" as CarouselJS
20+
21+/*! The Carousel component presents the items of a model in a carousel view. It's similar to a
22+ cover flow. But it stops at it's boundaries (therefore no PathView is used).
23+ */
24+Item {
25+ id: carousel
26+
27+ clip: true // Don't leak horizontally to other dashes
28+
29+ /// The component to be used as delegate. This component has to be derived from BaseCarouselDelegate
30+ property Component itemComponent
31+ /// Model for the Carousel, which has to be a model usable by a ListView
32+ property alias model: listView.model
33+ /// A minimal width of a tile can be set here. Per default a best fit will be calculated
34+ property alias minimumTileWidth: listView.minimumTileWidth
35+ /// Sets the number of tiles that are visible
36+ property alias pathItemCount: listView.pathItemCount
37+ /// Aspect ratio of the tiles width/height
38+ property alias tileAspectRatio: listView.tileAspectRatio
39+ /// Used to cache some delegates for performance reasons. See the ListView documentation for details
40+ property alias cacheBuffer: listView.cacheBuffer
41+ /// Width of the "draw buffer" in pixel. The drawBuffer is an additional area at start/end where
42+ /// items drawn, even if it is not in the visible area.
43+ /// cacheBuffer controls only the to retain delegates outside the visible area (and is used on top of the drawBuffer)
44+ /// see https://bugreports.qt-project.org/browse/QTBUG-29173
45+ property int drawBuffer: width / pathItemCount // an "ok" value - but values used from the listView cause loops
46+ /// The selected item can be shown in a different size controlled by selectedItemScaleFactor
47+ property real selectedItemScaleFactor: 1.1
48+ /// The index of the item that should be highlighted
49+ property alias highlightIndex: listView.highlightIndex
50+ /// exposes the delegate of the currentItem
51+ readonly property alias currentItem: listView.currentItem
52+ /// exposes the distance to the next row (only one row in carousel, so it's the topMargins)
53+ readonly property alias verticalSpacing: listView.verticalMargin
54+
55+ /// Emitted when the user clicked on an item
56+ /// @param index is the index of the clicked item
57+ /// @param model is the model of all the items in the carousel
58+ /// @param itemY is y of the clicked delegate
59+ signal clicked(int index, var model, real itemY)
60+
61+ /// Emitted when the user pressed and held on an item
62+ /// @param index is the index of the held item
63+ /// @param model is the model of all the items in the carousel
64+ /// @param itemY is y of the held delegate
65+ signal pressAndHold(int index, var model, real itemY)
66+
67+ implicitHeight: listView.tileHeight * selectedItemScaleFactor
68+
69+ /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
70+ One drawback is, that more delegates have to be drawn than usually. As some items are moved from the
71+ invisible to the visible area. Setting the cacheBuffer does not fix this.
72+ See https://bugreports.qt-project.org/browse/QTBUG-29173
73+ Therefore the ListView has negative left and right anchors margins, and in addition a header
74+ and footer item to compensate that.
75+
76+ The scaling of the items is controlled by the variable continuousIndex, described below. */
77+ ListView {
78+ id: listView
79+
80+ property real minimumTileWidth: 0
81+ property real newContentX: disabledNewContentX
82+ property real pathItemCount: referenceWidth / referenceTileWidth
83+ property real tileAspectRatio: 1
84+ property int highlightIndex: -1
85+
86+ /* The positioning and scaling of the items in the carousel is based on the variable
87+ 'continuousIndex', a continuous real variable between [0, 'carousel.model.count'],
88+ roughly representing the index of the item that is prioritised over the others.
89+ 'continuousIndex' is not linear, but is weighted depending on if it is close
90+ to the beginning of the content (beginning phase), in the middle (middle phase)
91+ or at the end (end phase).
92+ Each tile is scaled and transformed in proportion to the difference between
93+ its own index and continuousIndex.
94+ To efficiently calculate continuousIndex, we have these values:
95+ - 'gapToMiddlePhase' gap in pixels between beginning and middle phase
96+ - 'gapToEndPhase' gap in pixels between middle and end phase
97+ - 'kGapEnd' constant used to calculate 'continuousIndex' in end phase
98+ - 'kMiddleIndex' constant used to calculate 'continuousIndex' in middle phase
99+ - 'kXBeginningEnd' constant used to calculate 'continuousIndex' in beginning and end phase
100+ - 'realContentWidth' the width of all the delegates only (without header/footer)
101+ - 'realContentX' the 'contentX' of the listview ignoring the 'drawBuffer'
102+ - 'realWidth' the 'width' of the listview, as it is used as component. */
103+
104+ readonly property real gapToMiddlePhase: Math.min(realWidth / 2 - tileWidth / 2, (realContentWidth - realWidth) / 2)
105+ readonly property real gapToEndPhase: realContentWidth - realWidth - gapToMiddlePhase
106+ readonly property real kGapEnd: kMiddleIndex * (1 - gapToEndPhase / gapToMiddlePhase)
107+ readonly property real kMiddleIndex: (realWidth / 2) / tileWidth - 0.5
108+ readonly property real kXBeginningEnd: 1 / tileWidth + kMiddleIndex / gapToMiddlePhase
109+ readonly property real maximumItemTranslation: (listView.tileWidth * 3) / listView.scaleFactor
110+ readonly property real disabledNewContentX: -carousel.drawBuffer - 1
111+ readonly property real realContentWidth: contentWidth - 2 * carousel.drawBuffer
112+ readonly property real realContentX: contentX + carousel.drawBuffer
113+ readonly property real realPathItemCount: Math.min(realWidth / tileWidth, pathItemCount)
114+ readonly property real realWidth: carousel.width
115+ readonly property real referenceGapToMiddlePhase: realWidth / 2 - tileWidth / 2
116+ readonly property real referencePathItemCount: referenceWidth / referenceTileWidth
117+ readonly property real referenceWidth: 848
118+ readonly property real referenceTileWidth: 175
119+ readonly property real scaleFactor: tileWidth / referenceTileWidth
120+ readonly property real tileWidth: Math.max(realWidth / pathItemCount, minimumTileWidth)
121+ readonly property real tileHeight: tileWidth / tileAspectRatio
122+ readonly property real translationXViewFactor: 0.2 * (referenceGapToMiddlePhase / gapToMiddlePhase)
123+ readonly property real verticalMargin: (parent.height - tileHeight) / 2
124+ readonly property real visibleTilesScaleFactor: realPathItemCount / referencePathItemCount
125+
126+ anchors {
127+ fill: parent
128+ topMargin: verticalMargin
129+ bottomMargin: verticalMargin
130+ // extending the "drawing area"
131+ leftMargin: -carousel.drawBuffer
132+ rightMargin: -carousel.drawBuffer
133+ }
134+
135+ /* The header and footer help to "extend" the area, the listview draws items.
136+ This together with anchors.leftMargin and anchors.rightMargin. */
137+ header: Item {
138+ width: carousel.drawBuffer
139+ height: listView.tileHeight
140+ }
141+ footer: Item {
142+ width: carousel.drawBuffer
143+ height: listView.tileHeight
144+ }
145+
146+ boundsBehavior: Flickable.DragOverBounds
147+ cacheBuffer: carousel.cacheBuffer
148+ flickDeceleration: Math.max(1500 * Math.pow(realWidth / referenceWidth, 1.5), 1500) // 1500 is platform default
149+ maximumFlickVelocity: Math.max(2500 * Math.pow(realWidth / referenceWidth, 1.5), 2500) // 2500 is platform default
150+ orientation: ListView.Horizontal
151+
152+ function itemClicked(index, delegateItem) {
153+ listView.currentIndex = index
154+ var x = CarouselJS.getXFromContinuousIndex(index,
155+ realWidth,
156+ realContentWidth,
157+ tileWidth,
158+ gapToMiddlePhase,
159+ gapToEndPhase,
160+ carousel.drawBuffer)
161+
162+ if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
163+ /* We're clicking the selected item and
164+ we're in the neighbourhood of radius 1 pixel from it.
165+ Let's emit the clicked signal. */
166+ carousel.clicked(index, listView.model, delegateItem.y)
167+ return
168+ }
169+
170+ stepAnimation.stop()
171+ newContentXAnimation.stop()
172+
173+ newContentX = x
174+ newContentXAnimation.start()
175+ }
176+
177+ function itemPressAndHold(index, delegateItem) {
178+ var x = CarouselJS.getXFromContinuousIndex(index,
179+ realWidth,
180+ realContentWidth,
181+ tileWidth,
182+ gapToMiddlePhase,
183+ gapToEndPhase,
184+ carousel.drawBuffer);
185+
186+ if (Math.abs(x - contentX) < 1 && delegateItem !== undefined) {
187+ /* We're pressAndHold the selected item and
188+ we're in the neighbourhood of radius 1 pixel from it.
189+ Let's emit the pressAndHold signal. */
190+ carousel.pressAndHold(index, listView.model, delegateItem.y);
191+ return;
192+ }
193+
194+ stepAnimation.stop();
195+ newContentXAnimation.stop();
196+
197+ newContentX = x;
198+ newContentXAnimation.start();
199+ }
200+
201+ onHighlightIndexChanged: {
202+ if (highlightIndex != -1) {
203+ itemClicked(highlightIndex)
204+ }
205+ }
206+
207+ onMovementStarted: {
208+ stepAnimation.stop()
209+ newContentXAnimation.stop()
210+ newContentX = disabledNewContentX
211+ }
212+ onMovementEnded: {
213+ if (realContentX > 0 && realContentX < realContentWidth - realWidth)
214+ stepAnimation.start()
215+ }
216+
217+ SmoothedAnimation {
218+ id: stepAnimation
219+
220+ target: listView
221+ property: "contentX"
222+ to: CarouselJS.getXFromContinuousIndex(listView.selectedIndex,
223+ listView.realWidth,
224+ listView.realContentWidth,
225+ listView.tileWidth,
226+ listView.gapToMiddlePhase,
227+ listView.gapToEndPhase,
228+ carousel.drawBuffer)
229+ duration: 450
230+ velocity: 200
231+ easing.type: Easing.InOutQuad
232+ }
233+
234+ SequentialAnimation {
235+ id: newContentXAnimation
236+
237+ NumberAnimation {
238+ target: listView
239+ property: "contentX"
240+ from: listView.contentX
241+ to: listView.newContentX
242+ duration: 300
243+ easing.type: Easing.InOutQuad
244+ }
245+ ScriptAction {
246+ script: listView.newContentX = listView.disabledNewContentX
247+ }
248+ }
249+
250+ readonly property int selectedIndex: Math.round(continuousIndex)
251+ readonly property real continuousIndex: CarouselJS.getContinuousIndex(listView.realContentX,
252+ listView.tileWidth,
253+ listView.gapToMiddlePhase,
254+ listView.gapToEndPhase,
255+ listView.kGapEnd,
256+ listView.kMiddleIndex,
257+ listView.kXBeginningEnd)
258+
259+ property real viewTranslation: CarouselJS.getViewTranslation(listView.realContentX,
260+ listView.tileWidth,
261+ listView.gapToMiddlePhase,
262+ listView.gapToEndPhase,
263+ listView.translationXViewFactor)
264+
265+ delegate: Loader {
266+ property bool explicitlyScaled: explicitScaleFactor == carousel.selectedItemScaleFactor
267+ property real explicitScaleFactor: explicitScale ? carousel.selectedItemScaleFactor : 1.0
268+ readonly property bool explicitScale: (!listView.moving ||
269+ listView.realContentX <= 0 ||
270+ listView.realContentX >= listView.realContentWidth - listView.realWidth) &&
271+ listView.newContentX === listView.disabledNewContentX &&
272+ index === listView.selectedIndex
273+ readonly property real cachedTiles: listView.realPathItemCount + carousel.drawBuffer / listView.tileWidth
274+ readonly property real distance: listView.continuousIndex - index
275+ readonly property real itemTranslationScale: CarouselJS.getItemScale(0.5,
276+ (index + 0.5), // good approximation of scale while changing selected item
277+ listView.count,
278+ listView.visibleTilesScaleFactor)
279+ readonly property real itemScale: CarouselJS.getItemScale(distance,
280+ listView.continuousIndex,
281+ listView.count,
282+ listView.visibleTilesScaleFactor)
283+ readonly property real translationX: CarouselJS.getItemTranslation(index,
284+ listView.selectedIndex,
285+ distance,
286+ itemScale,
287+ itemTranslationScale,
288+ listView.maximumItemTranslation)
289+
290+ readonly property real xTransform: listView.viewTranslation + translationX * listView.scaleFactor
291+ readonly property real center: x - listView.contentX + xTransform - drawBuffer + (width/2)
292+
293+ width: listView.tileWidth
294+ height: listView.tileHeight
295+ scale: itemScale * explicitScaleFactor
296+ sourceComponent: itemComponent
297+ z: cachedTiles - Math.abs(index - listView.selectedIndex)
298+ opacity: highlightIndex == -1 ? 1 : (highlightIndex == index ? 0.6 : 0.2)
299+
300+ transform: Translate {
301+ x: xTransform
302+ }
303+
304+ Behavior on explicitScaleFactor {
305+ SequentialAnimation {
306+ ScriptAction {
307+ script: if (!explicitScale)
308+ explicitlyScaled = false
309+ }
310+ NumberAnimation {
311+ duration: explicitScaleFactor === 1.0 ? 250 : 150
312+ easing.type: Easing.InOutQuad
313+ }
314+ ScriptAction {
315+ script: if (explicitScale)
316+ explicitlyScaled = true
317+ }
318+ }
319+ }
320+
321+ onLoaded: {
322+ item.explicitlyScaled = Qt.binding(function() { return explicitlyScaled; })
323+ item.model = Qt.binding(function() { return model; })
324+ }
325+
326+ MouseArea {
327+ id: mouseArea
328+
329+ anchors.fill: parent
330+
331+ onClicked: {
332+ listView.itemClicked(index, item)
333+ }
334+
335+ onPressAndHold: {
336+ listView.itemPressAndHold(index, item)
337+ }
338+
339+ }
340+ }
341+ }
342+}
tests/mocks/QMenuModel/actionstateparser.cpp → Components/Circle.qmlrenamed+6−3
@@ -12,8 +12,11 @@
12 *
12 *
13 * You should have received a copy of the GNU General Public License
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17 */
15 */
18
16
19−#include "actionstateparser.h"
17+import QtQuick 2.0
18+
19+Rectangle {
20+ antialiasing: true
21+ radius: width / 2
22+ }
qml/Components/DragHandle.qml → Components/DragHandle.qmlrenamed+53−69
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013,2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,10 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20+import "Math.js" as MathLocal
20
21
21/*
22/*
22 Put a DragHandle inside a Showable to enable the user to drag it from that handle.
23 Put a DragHandle inside a Showable to enable the user to drag it from that handle.
@@ -38,13 +39,18 @@ import Ubuntu.Gestures 0.1
38 anchors.bottom: parent.bottom
39 anchors.bottom: parent.bottom
39 width: units.gu(2)
40 width: units.gu(2)
40
41
41− direction: SwipeArea::Leftwards
42+ direction: DirectionalDragArea::Leftwards
42 }
43 }
43 }
44 }
44
45
45 */
46 */
46−SwipeArea {
47+EdgeDragArea {
47 id: dragArea
48 id: dragArea
49+ objectName: "dragHandle"
50+
51+ // Disable gesture detection by default when hinting is used.
52+ // It doesn't make sense to have both.
53+ distanceThreshold: hintDisplacement > 0 ? 0 : units.gu(1.5)
48
54
49 property bool stretch: false
55 property bool stretch: false
50
56
@@ -60,27 +66,21 @@ SwipeArea {
60 }
66 }
61
67
62 property real hintDisplacement: 0
68 property real hintDisplacement: 0
63−
64− immediateRecognition: hintDisplacement > 0
65−
66− property var overrideStartValue: undefined
67 SmoothedAnimation {
69 SmoothedAnimation {
68 id: hintingAnimation
70 id: hintingAnimation
69 target: hintingAnimation
71 target: hintingAnimation
70− objectName: "hintingAnimation"
71 property: "targetValue"
72 property: "targetValue"
72 duration: 150
73 duration: 150
73 velocity: -1
74 velocity: -1
74−
75− to: d.incrementTargetProp ? d.startValue + hintDisplacement
75+ to: Direction.isPositive(direction) ? d.startValue + hintDisplacement
76− : d.startValue - hintDisplacement
76+ : d.startValue - hintDisplacement
77 property real targetValue
77 property real targetValue
78 onTargetValueChanged: {
78 onTargetValueChanged: {
79 if (!running) {
79 if (!running) {
80 return;
80 return;
81 }
81 }
82
82
83− if (d.incrementTargetProp) {
83+ if (Direction.isPositive(direction)) {
84 if (parent[d.targetProp] < targetValue) {
84 if (parent[d.targetProp] < targetValue) {
85 parent[d.targetProp] = targetValue;
85 parent[d.targetProp] = targetValue;
86 }
86 }
@@ -95,24 +95,12 @@ SwipeArea {
95 // Private stuff
95 // Private stuff
96 QtObject {
96 QtObject {
97 id: d
97 id: d
98−
98+ property var previousStatus: undefined
99− // Whether movement along the designated direction will increment the value of the target property
100− readonly property bool incrementTargetProp: (Direction.isPositive(direction) && !dragArea.stretch)
101− || (dragArea.stretch && !d.dragParent.shown)
102−
103 property real startValue
99 property real startValue
104− property real minValue: {
100+ property real minValue: Direction.isPositive(direction) ? startValue
105− if (direction == Direction.Horizontal) {
106− return startValue - maxTotalDragDistance;
107− } else if (incrementTargetProp) {
108− return startValue;
109− } else {
110− return startValue - maxTotalDragDistance;
101+ : startValue - maxTotalDragDistance
111− }
112− }
113−
114− property real maxValue: incrementTargetProp ? startValue + maxTotalDragDistance
102+ property real maxValue: Direction.isPositive(direction) ? startValue + maxTotalDragDistance
115− : startValue;
103+ : startValue
116
104
117 property var dragParent: dragArea.parent
105 property var dragParent: dragArea.parent
118
106
@@ -125,26 +113,26 @@ SwipeArea {
125 }
113 }
126 }
114 }
127
115
128− function limitMovement(distance) {
116+ function limitMovement(step) {
129− var targetValue = MathUtils.clamp(d.startValue + distance, minValue, maxValue);
117+ var targetValue = MathLocal.clamp(dragParent[targetProp] + step, minValue, maxValue);
130− var diff = targetValue - d.startValue;
118+ var step = targetValue - dragParent[targetProp];
131
119
132 if (hintDisplacement == 0) {
120 if (hintDisplacement == 0) {
133− return diff;
121+ return step;
134 }
122 }
135
123
136 // we should not go behind hintingAnimation's current value
124 // we should not go behind hintingAnimation's current value
137− if (d.incrementTargetProp) {
125+ if (Direction.isPositive(direction)) {
138− if (d.startValue + diff < hintingAnimation.targetValue) {
126+ if (dragParent[targetProp] + step < hintingAnimation.targetValue) {
139− diff = hintingAnimation.targetValue - d.startValue;
127+ step = hintingAnimation.targetValue - dragParent[targetProp];
140 }
128 }
141 } else {
129 } else {
142− if (d.startValue + diff > hintingAnimation.targetValue) {
130+ if (dragParent[targetProp] + step > hintingAnimation.targetValue) {
143− diff = hintingAnimation.targetValue - d.startValue;
131+ step = hintingAnimation.targetValue - dragParent[targetProp];
144 }
132 }
145 }
133 }
146
134
147− return diff;
135+ return step;
148 }
136 }
149
137
150 function onFinishedRecognizedGesture() {
138 function onFinishedRecognizedGesture() {
@@ -177,51 +165,47 @@ SwipeArea {
177 EdgeDragEvaluator {
165 EdgeDragEvaluator {
178 objectName: "edgeDragEvaluator"
166 objectName: "edgeDragEvaluator"
179 id: dragEvaluator
167 id: dragEvaluator
180− // Effectively convert distance into the drag position projected onto the gesture direction axis
168+ trackedPosition: sceneDistance
181− trackedPosition: Direction.isPositive(dragArea.direction) ? distance : -distance
182 maxDragDistance: maxTotalDragDistance
169 maxDragDistance: maxTotalDragDistance
183 direction: dragArea.direction
170 direction: dragArea.direction
184 }
171 }
185
172
186 onDistanceChanged: {
173 onDistanceChanged: {
187− if (dragging) {
174+ if (status === DirectionalDragArea.Recognized) {
188− if (!Direction.isPositive(direction))
175+ // don't go the whole distance in order to smooth out the movement
189− distance = -distance;
190−
191− if (dragArea.stretch &&
192− ((!Direction.isPositive(direction) && !d.dragParent.shown)
193− ||
194− (Direction.isPositive(direction) && d.dragParent.shown))
195− )
196− {
197− // This happens when you have a stretching showable being shown from the right or
198− // top edge (and consequently being hidden when dragged towards the right/top edge)
199− // In those situations, dimension expansion/retraction happens in the opposite
200− // sign of the axis direction
201− distance = -distance;
176+ var step = distance * 0.3;
202− }
177+
178+ step = d.limitMovement(step);
203
179
204− var toAdd = d.limitMovement(distance);
205− parent[d.targetProp] = d.startValue + toAdd;
180+ parent[d.targetProp] += step;
206 }
181 }
207 }
182 }
208
183
209 onDraggingChanged: {
184 onDraggingChanged: {
210 if (dragging) {
185 if (dragging) {
211− dragEvaluator.reset();
212− if (overrideStartValue !== undefined) {
213− d.startValue = overrideStartValue;
214− } else {
215− d.startValue = parent[d.targetProp];
216− }
217−
218 if (hintDisplacement > 0) {
186 if (hintDisplacement > 0) {
219 hintingAnimation.targetValue = d.startValue;
187 hintingAnimation.targetValue = d.startValue;
220 hintingAnimation.start();
188 hintingAnimation.start();
221 }
189 }
222 } else {
190 } else {
223 hintingAnimation.stop();
191 hintingAnimation.stop();
224− d.onFinishedRecognizedGesture();
225 }
192 }
226 }
193 }
194+
195+ onStatusChanged: {
196+ if (status === DirectionalDragArea.WaitingForTouch) {
197+ if (d.previousStatus === DirectionalDragArea.Recognized) {
198+ d.onFinishedRecognizedGesture();
199+ }
200+ d.startValue = parent[d.targetProp];
201+ }
202+
203+ if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
204+ d.previousStatus === undefined) {
205+ dragEvaluator.reset();
206+ d.startValue = parent[d.targetProp];
207+ }
208+
209+ d.previousStatus = status;
210+ }
227}
211}
qml/Components/DraggingArea.qml → Components/DraggingArea.qmlrenamed+4−7
@@ -14,8 +14,9 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19+import "Math.js" as MathLocal
19
20
20MouseArea {
21MouseArea {
21 id: draggingArea
22 id: draggingArea
@@ -25,7 +26,7 @@ MouseArea {
25 property real dragVelocity: 0
26 property real dragVelocity: 0
26 property real dragValue: (orientation == Qt.Vertical ? (mouseY - __pressedPosition.y)
27 property real dragValue: (orientation == Qt.Vertical ? (mouseY - __pressedPosition.y)
27 : (mouseX - __pressedPosition.x))
28 : (mouseX - __pressedPosition.x))
28− property real lateralPosition: orientation == Qt.Horizontal ? MathUtils.clamp(mouseY, 0, height) : MathUtils.clamp(mouseX, 0, width)
29+ property real lateralPosition: orientation == Qt.Horizontal ? MathLocal.clamp(mouseY, 0, height) : MathLocal.clamp(mouseX, 0, width)
29 property point __pressedPosition: Qt.point(0, 0)
30 property point __pressedPosition: Qt.point(0, 0)
30 property var __dragEvents: []
31 property var __dragEvents: []
31 property bool clickValidated: true
32 property bool clickValidated: true
@@ -117,8 +118,4 @@ MouseArea {
117 dragging = false
118 dragging = false
118 __pressedPosition = Qt.point(mouse.x, mouse.y)
119 __pressedPosition = Qt.point(mouse.x, mouse.y)
119 }
120 }
120−
121− onCanceled: {
122− dragging = false
123− }
124}
121}
Components/EdgeDemo.qmlnew file+238
@@ -0,0 +1,238 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import AccountsService 0.1
18+import LightDM 0.1 as LightDM
19+import QtQuick 2.0
20+
21+Item {
22+ id: demo
23+
24+ property Item greeter
25+ property Item dash
26+ property Item launcher
27+ property Item indicators
28+ property Item underlay
29+
30+ property bool launcherEnabled: true
31+ property bool dashEnabled: true
32+ property bool panelEnabled: true
33+ property bool panelContentEnabled: true
34+
35+ property bool paused: false
36+
37+ onPausedChanged: {
38+ if (d.rightEdgeDemo) d.rightEdgeDemo.paused = paused
39+ if (d.topEdgeDemo) d.topEdgeDemo.paused = paused
40+ if (d.bottomEdgeDemo) d.bottomEdgeDemo.paused = paused
41+ if (d.leftEdgeDemo) d.leftEdgeDemo.paused = paused
42+ if (d.finalEdgeDemo) d.finalEdgeDemo.paused = paused
43+ }
44+
45+ function hideEdgeDemoInShell() {
46+ AccountsService.demoEdges = false;
47+ stopDemo();
48+ }
49+
50+ function hideEdgeDemoInGreeter() {
51+ // TODO: AccountsService.demoEdges = false as lightdm user
52+ }
53+
54+ function hideEdgeDemos() {
55+ hideEdgeDemoInGreeter();
56+ hideEdgeDemoInShell();
57+ }
58+
59+ function stopDemo() {
60+ launcherEnabled = true
61+ dashEnabled = true
62+ panelEnabled = true
63+ panelContentEnabled = true
64+ if (d.rightEdgeDemo) d.rightEdgeDemo.destroy()
65+ if (d.topEdgeDemo) d.topEdgeDemo.destroy()
66+ if (d.bottomEdgeDemo) d.bottomEdgeDemo.destroy()
67+ if (d.leftEdgeDemo) d.leftEdgeDemo.destroy()
68+ if (d.finalEdgeDemo) d.finalEdgeDemo.destroy()
69+ }
70+
71+ function startDemo() {
72+ if (!d.overlay) {
73+ d.overlay = Qt.createComponent("EdgeDemoOverlay.qml")
74+ }
75+
76+ launcherEnabled = false;
77+ dashEnabled = false;
78+ panelEnabled = false;
79+ panelContentEnabled = false;
80+
81+ // Begin with either greeter or dash, depending on which is visible
82+ if (greeter && greeter.shown) {
83+ startRightEdgeDemo()
84+ } else {
85+ startTopEdgeDemo()
86+ }
87+ }
88+
89+ QtObject {
90+ id: d
91+ property Component overlay
92+ property QtObject rightEdgeDemo
93+ property QtObject topEdgeDemo
94+ property QtObject bottomEdgeDemo
95+ property QtObject leftEdgeDemo
96+ property QtObject finalEdgeDemo
97+ property bool showEdgeDemo: AccountsService.demoEdges
98+ property bool showEdgeDemoInGreeter: AccountsService.demoEdges // TODO: AccountsService.demoEdges as lightdm user
99+
100+ onShowEdgeDemoChanged: {
101+ stopDemo()
102+ if (d.showEdgeDemo) {
103+ startDemo()
104+ }
105+ }
106+ }
107+
108+ function startRightEdgeDemo() {
109+ if (demo.greeter) {
110+ d.rightEdgeDemo = d.overlay.createObject(demo.greeter, {
111+ "edge": "right",
112+ "title": i18n.tr("Right edge"),
113+ "text": i18n.tr("Try swiping from the right edge to unlock the phone"),
114+ "anchors.fill": demo.greeter,
115+ });
116+ }
117+ if (d.rightEdgeDemo) {
118+ d.rightEdgeDemo.onSkip.connect(demo.hideEdgeDemos)
119+ } else {
120+ stopDemo();
121+ }
122+ }
123+
124+ Connections {
125+ target: demo.greeter
126+
127+ function hide() {
128+ if (d.rightEdgeDemo && d.rightEdgeDemo.available) {
129+ d.rightEdgeDemo.hide()
130+ hideEdgeDemoInGreeter()
131+ startTopEdgeDemo()
132+ }
133+ }
134+
135+ onUnlocked: hide()
136+ onShownChanged: if (!greeter.shown) hide()
137+ }
138+
139+ function startTopEdgeDemo() {
140+ demo.panelEnabled = true;
141+ if (demo.dash && demo.underlay) {
142+ d.topEdgeDemo = d.overlay.createObject(demo.underlay, {
143+ "edge": "top",
144+ "title": i18n.tr("Top edge"),
145+ "text": i18n.tr("Try swiping from the top edge to access the indicators"),
146+ "anchors.fill": demo.dash,
147+ });
148+ }
149+ if (d.topEdgeDemo) {
150+ d.topEdgeDemo.onSkip.connect(demo.hideEdgeDemoInShell)
151+ } else {
152+ stopDemo();
153+ }
154+ }
155+
156+ Connections {
157+ target: demo.indicators
158+ onFullyOpenedChanged: {
159+ if (d.topEdgeDemo && d.topEdgeDemo.available && demo.indicators.fullyOpened) {
160+ d.topEdgeDemo.hideNow()
161+ startBottomEdgeDemo()
162+ }
163+ }
164+ }
165+
166+ function startBottomEdgeDemo() {
167+ if (demo.indicators) {
168+ d.bottomEdgeDemo = d.overlay.createObject(demo.indicators, {
169+ "edge": "bottom",
170+ "title": i18n.tr("Close"),
171+ "text": i18n.tr("Swipe up again to close the settings screen"),
172+ "anchors.fill": demo.indicators.content,
173+ });
174+ }
175+ if (d.bottomEdgeDemo) {
176+ d.bottomEdgeDemo.onSkip.connect(demo.hideEdgeDemoInShell)
177+ } else {
178+ stopDemo();
179+ }
180+ }
181+
182+ Connections {
183+ target: demo.indicators
184+ onPartiallyOpenedChanged: {
185+ if (d.bottomEdgeDemo && d.bottomEdgeDemo.available && !demo.indicators.partiallyOpened && !demo.indicators.fullyOpened) {
186+ d.bottomEdgeDemo.hideNow()
187+ startLeftEdgeDemo()
188+ }
189+ }
190+ }
191+
192+ function startLeftEdgeDemo() {
193+ demo.panelEnabled = false;
194+ demo.launcherEnabled = true;
195+ if (demo.dash && demo.underlay) {
196+ d.leftEdgeDemo = d.overlay.createObject(demo.underlay, {
197+ "edge": "left",
198+ "title": i18n.tr("Left edge"),
199+ "text": i18n.tr("Swipe from the left to reveal the launcher for quick access to apps"),
200+ "anchors.fill": demo.dash,
201+ });
202+ }
203+ if (d.leftEdgeDemo) {
204+ d.leftEdgeDemo.onSkip.connect(demo.hideEdgeDemoInShell)
205+ } else {
206+ stopDemo();
207+ }
208+ }
209+
210+ Connections {
211+ target: demo.launcher
212+ onStateChanged: {
213+ if (d.leftEdgeDemo && d.leftEdgeDemo.available && launcher.state == "visible") {
214+ d.leftEdgeDemo.hide()
215+ launcher.hide()
216+ startFinalEdgeDemo()
217+ }
218+ }
219+ }
220+
221+ function startFinalEdgeDemo() {
222+ demo.launcherEnabled = false;
223+ if (demo.dash && demo.underlay) {
224+ d.finalEdgeDemo = d.overlay.createObject(demo.underlay, {
225+ "edge": "none",
226+ "title": i18n.tr("Well done"),
227+ "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap anywhere to start"),
228+ "anchors.fill": demo.dash,
229+ "showSkip": false,
230+ });
231+ }
232+ if (d.finalEdgeDemo) {
233+ d.finalEdgeDemo.onSkip.connect(demo.hideEdgeDemoInShell)
234+ } else {
235+ stopDemo();
236+ }
237+ }
238+}
Components/EdgeDemoOverlay.qmlnew file+271
@@ -0,0 +1,271 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import Powerd 0.1
18+import QtQuick 2.0
19+import QtGraphicalEffects 1.0
20+import Unity.Application 0.1
21+import Ubuntu.Components 0.1
22+
23+Showable {
24+ id: overlay
25+
26+ /*
27+ * Valid values are "left", "right", "top", "bottom", or "none".
28+ */
29+ property string edge: "top"
30+
31+ /*
32+ * This is the header displayed, like "Right edge".
33+ */
34+ property alias title: titleLabel.text
35+
36+ /*
37+ * This is the block of text displayed below the header.
38+ */
39+ property alias text: textLabel.text
40+
41+ /*
42+ * This is the text for the skip button.
43+ */
44+ property alias skipText: skipLabel.text
45+
46+ /*
47+ * This is the visible status of the skip button.
48+ */
49+ property alias showSkip: skipLabel.visible
50+
51+ /*
52+ * Whether this demo is running currently.
53+ */
54+ readonly property bool active: available && visible
55+
56+ /*
57+ * Whether animations are paused.
58+ */
59+ property alias paused: wholeAnimation.paused
60+
61+ /*
62+ * Whether animations are running.
63+ */
64+ readonly property alias running: wholeAnimation.running
65+
66+ signal skip()
67+
68+ function doSkip() {
69+ d.skipOnHide = true;
70+ hide();
71+ }
72+
73+ function hideNow() {
74+ overlay.visible = false;
75+ overlay.available = false;
76+ if (d.skipOnHide) {
77+ overlay.skip();
78+ }
79+ }
80+
81+ showAnimation: StandardAnimation {
82+ property: "opacity"
83+ to: 1
84+ onRunningChanged: if (running) overlay.visible = true
85+ }
86+ hideAnimation: StandardAnimation {
87+ property: "opacity"
88+ to: 0
89+ duration: UbuntuAnimation.BriskDuration
90+ onRunningChanged: if (!running) overlay.hideNow()
91+ }
92+
93+ QtObject {
94+ id: d
95+ property bool skipOnHide: false
96+ property int edgeMargin: units.gu(4)
97+ }
98+
99+ Rectangle {
100+ objectName: "backgroundShade"
101+
102+ anchors.fill: parent
103+ color: "black"
104+ opacity: 0.8
105+ visible: overlay.active
106+
107+ MouseArea {
108+ anchors.fill: parent
109+ enabled: overlay.edge == "none" && overlay.opacity == 1.0
110+ onClicked: overlay.doSkip()
111+ }
112+ }
113+
114+ Item {
115+ id: hintGroup
116+ x: 0
117+ y: 0
118+ width: parent.width
119+ height: parent.height
120+ visible: overlay.active
121+
122+ Column {
123+ id: labelGroup
124+ spacing: units.gu(3)
125+
126+ anchors {
127+ margins: d.edgeMargin
128+ left: parent.left
129+ top: overlay.edge == "bottom" ? undefined : parent.top
130+ bottom: overlay.edge == "bottom" ? parent.bottom : undefined
131+ }
132+
133+ Label {
134+ id: titleLabel
135+ fontSize: "x-large"
136+ width: units.gu(25)
137+ wrapMode: Text.WordWrap
138+ }
139+
140+ Label {
141+ id: textLabel
142+ width: units.gu(25)
143+ wrapMode: Text.WordWrap
144+ }
145+
146+ Label {
147+ id: skipLabel
148+ objectName: "skipLabel"
149+ text: i18n.tr("Skip intro")
150+ color: UbuntuColors.orange
151+ fontSize: "small"
152+
153+ Icon {
154+ anchors.left: parent.right
155+ anchors.verticalCenter: parent.verticalCenter
156+ height: units.dp(12)
157+ width: units.dp(12)
158+ name: "chevron"
159+ color: UbuntuColors.orange
160+ }
161+
162+ MouseArea {
163+ // Make clickable area bigger than just the link because
164+ // otherwise, the edge demo will feel hard to dismiss.
165+ anchors.fill: parent
166+ anchors.margins: -units.gu(5)
167+ onClicked: overlay.doSkip()
168+ }
169+ }
170+ }
171+
172+ LinearGradient {
173+ id: edgeHint
174+ property int size: 1
175+ cached: false
176+ visible: overlay.edge != "none"
177+ gradient: Gradient {
178+ GradientStop {
179+ position: 0.0
180+ color: Qt.hsla(16.0/360.0, 0.83, 0.47, 0.4) // UbuntuColors.orange, but transparent
181+ }
182+ GradientStop {
183+ position: 1.0
184+ color: "transparent"
185+ }
186+ }
187+ anchors.fill: parent
188+ start: {
189+ if (overlay.edge == "right") {
190+ return Qt.point(width, 0);
191+ } else if (overlay.edge == "left") {
192+ return Qt.point(0, 0);
193+ } else if (overlay.edge == "top") {
194+ return Qt.point(0, 0);
195+ } else {
196+ return Qt.point(0, height);
197+ }
198+ }
199+ end: {
200+ if (overlay.edge == "right") {
201+ return Qt.point(width - size, 0);
202+ } else if (overlay.edge == "left") {
203+ return Qt.point(size, 0);
204+ } else if (overlay.edge == "top") {
205+ return Qt.point(0, size);
206+ } else {
207+ return Qt.point(0, height - size);
208+ }
209+ }
210+ }
211+ }
212+
213+ SequentialAnimation {
214+ id: wholeAnimation
215+ objectName: "wholeAnimation"
216+ running: overlay.active
217+
218+ ParallelAnimation {
219+ id: fadeInAnimation
220+
221+ StandardAnimation {
222+ target: labelGroup
223+ property: {
224+ if (overlay.edge == "right" || overlay.edge == "left") {
225+ return "anchors.leftMargin";
226+ } else if (overlay.edge == "bottom") {
227+ return "anchors.bottomMargin";
228+ } else {
229+ return "anchors.topMargin";
230+ }
231+ }
232+ from: {
233+ if (overlay.edge == "right") {
234+ return d.edgeMargin + units.gu(3)
235+ } else {
236+ return d.edgeMargin - units.gu(3)
237+ }
238+ }
239+ to: d.edgeMargin
240+ duration: overlay.edge == "none" ? 0 : UbuntuAnimation.SleepyDuration
241+ }
242+ StandardAnimation {
243+ target: overlay
244+ property: "opacity"
245+ from: 0.0
246+ to: 1.0
247+ duration: UbuntuAnimation.SleepyDuration
248+ }
249+ }
250+
251+ SequentialAnimation {
252+ id: hintAnimation
253+ loops: Animation.Infinite
254+ property string prop: (overlay.edge == "left" || overlay.edge == "right") ? "x" : "y"
255+ property double endVal: units.dp(5) * ((overlay.edge == "left" || overlay.edge == "top") ? 1 : -1)
256+ property double maxGlow: units.dp(20)
257+ property int duration: overlay.edge == "none" ? 0 : UbuntuAnimation.SleepyDuration
258+
259+ ParallelAnimation {
260+ StandardAnimation { target: hintGroup; property: hintAnimation.prop; from: 0; to: hintAnimation.endVal; duration: hintAnimation.duration }
261+ StandardAnimation { target: edgeHint; property: "size"; from: 1; to: hintAnimation.maxGlow; duration: hintAnimation.duration }
262+ }
263+
264+ // Undo the above
265+ ParallelAnimation {
266+ StandardAnimation { target: hintGroup; property: hintAnimation.prop; from: hintAnimation.endVal; to: 0; duration: hintAnimation.duration }
267+ StandardAnimation { target: edgeHint; property: "size"; from: hintAnimation.maxGlow; to: 1; duration: hintAnimation.duration }
268+ }
269+ }
270+ }
271+}
Components/EdgeDragArea.qmlnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Gestures 0.1
20+
21+/*
22+ A DirectionalDragArea wrapper that provides some well-chosen defaults
23+ for its gesture recognition parameters.
24+*/
25+DirectionalDragArea {
26+
27+ // TODO: Re-evaluate those or even the recognition heuristics itself once
28+ // we have gesture cancelling/forwarding in place.
29+ //
30+ // The idea here is that it's better having lax rules than false negatives.
31+ // False negatives are very frustrating to the user.
32+ maxDeviation: units.gu(3)
33+ wideningAngle: 50
34+ distanceThreshold: units.gu(1.5)
35+ minSpeed: units.gu(0) // some people were getting false negatives with it enabled.
36+}
qml/Components/EdgeDragEvaluator.qml → Components/EdgeDragEvaluator.qmlrenamed+11−20
@@ -14,8 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20
20
21/*
21/*
@@ -53,20 +53,20 @@ AxisVelocityCalculator {
53 // Returns whether the drag should continue by itself until completed.
53 // Returns whether the drag should continue by itself until completed.
54 function shouldAutoComplete() {
54 function shouldAutoComplete() {
55 var deltaPos = trackedPosition - __startPosition;
55 var deltaPos = trackedPosition - __startPosition;
56−
57 if (Math.abs(deltaPos) < minDragDistance) {
56 if (Math.abs(deltaPos) < minDragDistance) {
58 velocity = 0;
57 velocity = 0;
59 minVelocity = 0;
58 minVelocity = 0;
60 return false;
59 return false;
61 }
60 }
62
61
62+ minVelocity = __calculateMinimumVelocityForAutoCompletion(deltaPos);
63 velocity = calculate();
63 velocity = calculate();
64− minVelocity = __calculateMinimumVelocityForAutoCompletion();
65
64
66− if (_dragDirectionIsPositive()) {
65+ if (Direction.isPositive(direction) && (velocity >= minVelocity)
67− return velocity >= minVelocity;
66+ || !Direction.isPositive(direction) && (velocity <= minVelocity)) {
67+ return true;
68 } else {
68 } else {
69− return velocity <= minVelocity;
69+ return false;
70 }
70 }
71 }
71 }
72
72
@@ -75,20 +75,11 @@ AxisVelocityCalculator {
75 // speedThreshold in pixels per millisecond
75 // speedThreshold in pixels per millisecond
76 property real __speedThresholdMs: speedThreshold / 1000.0
76 property real __speedThresholdMs: speedThreshold / 1000.0
77
77
78− function _dragDirectionIsPositive() {
79− if (direction === Direction.Horizontal) {
80− return (trackedPosition - __startPosition) > 0;
81− } else {
82− return Direction.isPositive(direction);
83− }
84− }
85−
86− function __calculateMinimumVelocityForAutoCompletion() {
87− // Minimum velocity when a drag total distance is zero
78+ // Minimum velocity when a drag total distance is zero
88− var v0 = _dragDirectionIsPositive() ? __speedThresholdMs : - __speedThresholdMs;
79+ property real __v0: Direction.isPositive(direction) ? __speedThresholdMs : - __speedThresholdMs
89− var deltaPos = trackedPosition - __startPosition;
90
80
81+ function __calculateMinimumVelocityForAutoCompletion(distance) {
91− return v0 - ((__speedThresholdMs / dragThreshold) * deltaPos);
82+ return __v0 - ((__speedThresholdMs / dragThreshold) * distance);
92 }
83 }
93
84
94 function reset() {
85 function reset() {
Components/FilterGrid.qmlnew file+111
@@ -0,0 +1,111 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Utils 0.1
20+import "../Components"
21+
22+/*
23+ A ResponsiveGridView that can optionally have the number of rows being displayed
24+ reduced to collapsedRowCount, in which case a button saying "View all (123)"
25+ will be shown at the bottom. If clicked, FilterGrid will them expand vertically
26+ to display all rows.
27+ */
28+Item {
29+ id: root
30+
31+ /* If true, the number of elements displayed will be limited by collapsedRowCount.
32+ If false, all elements will be displayed, effectively looking the same as a regular
33+ ResponsiveGridView. */
34+ property bool filter: true
35+
36+ /* Whether, when collapsed, a button should be displayed enabling the user to expand
37+ the grid to its full size. */
38+ readonly property bool expandable: model.count > collapsedRowCount * iconTileGrid.columns
39+
40+ property var model: null
41+
42+ /* Maximum number of rows to be show when filter=true. */
43+ property int collapsedRowCount: 2
44+ readonly property int collapsedHeight: {
45+ return iconTileGrid.contentHeightForRows(Math.min(collapsedRowCount, Math.ceil(model.count / columns)))
46+ }
47+ readonly property int uncollapsedHeight: {
48+ return iconTileGrid.contentHeightForRows(Math.ceil(model.count / columns))
49+ }
50+
51+ property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
52+ property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
53+ property alias columns: iconTileGrid.columns
54+ property alias delegateWidth: iconTileGrid.delegateWidth
55+ property alias delegateHeight: iconTileGrid.delegateHeight
56+ property alias verticalSpacing: iconTileGrid.verticalSpacing
57+ readonly property alias margins: iconTileGrid.margins
58+ property alias delegate: iconTileGrid.delegate
59+ property alias cellWidth: iconTileGrid.cellWidth
60+ property alias cellHeight: iconTileGrid.cellHeight
61+ property alias delegateCreationBegin: iconTileGrid.delegateCreationBegin
62+ property alias delegateCreationEnd: iconTileGrid.delegateCreationEnd
63+ readonly property alias flicking: iconTileGrid.flicking
64+ readonly property alias moving: iconTileGrid.moving
65+ readonly property alias pressDelay: iconTileGrid.pressDelay
66+ property alias highlightIndex: iconTileGrid.highlightIndex
67+ readonly property alias currentItem: iconTileGrid.currentItem
68+
69+ height: !filterAnimation.running ? childrenRect.height : height
70+ clip: filterAnimation.running
71+
72+ NumberAnimation {
73+ property bool filterEndValue
74+ id: filterAnimation
75+ target: root
76+ property: "height"
77+ to: filterEndValue ? root.collapsedHeight : root.uncollapsedHeight
78+ // Duration and easing here match the ListViewWithPageHeader::m_contentYAnimation
79+ // otherwise since both animations can run at the same time you'll get
80+ // some visual weirdness.
81+ duration: 200
82+ easing.type: Easing.InOutQuad
83+ onStopped: {
84+ root.filter = filterEndValue;
85+ }
86+ }
87+
88+ function startFilterAnimation(filter) {
89+ filterAnimation.filterEndValue = filter
90+ filterAnimation.start();
91+ }
92+
93+ ResponsiveGridView {
94+ id: iconTileGrid
95+
96+ anchors { left: parent.left; right: parent.right }
97+ height: totalContentHeight
98+ interactive: false
99+
100+ minimumHorizontalSpacing: units.gu(0.5)
101+ maximumNumberOfColumns: 6
102+ delegateWidth: units.gu(11)
103+ delegateHeight: units.gu(9.5)
104+ verticalSpacing: units.gu(2)
105+
106+ model: LimitProxyModel {
107+ model: root.model
108+ limit: (filter && !filterAnimation.running) ? collapsedRowCount * iconTileGrid.columns : -1
109+ }
110+ }
111+}
qml/Components/LazyImage.qml → Components/LazyImage.qmlrenamed+15−32
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013-2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * Authors:
4 * Authors:
5 * Michał Sawicz <michal.sawicz@canonical.com>
5 * Michał Sawicz <michal.sawicz@canonical.com>
@@ -17,8 +17,8 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
18 */
19
19
20−import QtQuick 2.4
20+import QtQuick 2.0
21−import Ubuntu.Components 1.3
21+import Ubuntu.Components 0.1
22
22
23Item {
23Item {
24 id: root
24 id: root
@@ -29,15 +29,13 @@ Item {
29
29
30 property real initialWidth: scaleTo == "width" || scaleTo == "fit" ? width : units.gu(10)
30 property real initialWidth: scaleTo == "width" || scaleTo == "fit" ? width : units.gu(10)
31 property real initialHeight: scaleTo == "height" || scaleTo == "fit" ? height : units.gu(10)
31 property real initialHeight: scaleTo == "height" || scaleTo == "fit" ? height : units.gu(10)
32− property real lastScaledDimension: scaleTo == "height" || scaleTo == "fit" ? width : height
33
32
34 property alias sourceSize: image.sourceSize
33 property alias sourceSize: image.sourceSize
34+ property alias fillMode: image.fillMode
35 property alias asynchronous: image.asynchronous
35 property alias asynchronous: image.asynchronous
36 property alias cache: image.cache
36 property alias cache: image.cache
37− property alias sourceImage: image
37+ property alias horizontalAlignment: image.horizontalAlignment
38−
38+ property alias verticalAlignment: image.verticalAlignment
39− property bool useUbuntuShape: true
40− property bool pressed: false
41
39
42 state: "default"
40 state: "default"
43
41
@@ -50,16 +48,12 @@ Item {
50 }
48 }
51 }
49 }
52
50
53− Loader {
51+ UbuntuShape {
54 id: placeholder
52 id: placeholder
55 objectName: "placeholder"
53 objectName: "placeholder"
54+ color: "#22FFFFFF"
56 anchors.fill: shape
55 anchors.fill: shape
57− active: useUbuntuShape
58 visible: opacity != 0
56 visible: opacity != 0
59− sourceComponent: UbuntuShape {
60− aspect: UbuntuShape.Flat
61− backgroundColor: "#22FFFFFF"
62− }
63
57
64 ActivityIndicator {
58 ActivityIndicator {
65 id: activity
59 id: activity
@@ -82,43 +76,33 @@ Item {
82 }
76 }
83 }
77 }
84
78
85− Loader {
79+ UbuntuShape {
86 id: shape
80 id: shape
87 objectName: "shape"
81 objectName: "shape"
88 height: root.initialHeight
82 height: root.initialHeight
89 width: root.initialWidth
83 width: root.initialWidth
90 anchors.centerIn: root.scaleTo == "fit" ? parent : undefined
84 anchors.centerIn: root.scaleTo == "fit" ? parent : undefined
91− active: useUbuntuShape
85+
92 opacity: 0
86 opacity: 0
93 visible: opacity != 0
87 visible: opacity != 0
94− sourceComponent: UbuntuShapeOverlay {
95− property bool pressed: false
96− aspect: UbuntuShape.Flat
97− overlayColor: Qt.rgba(0, 0, 0, pressed ? 0.1 : 0)
98− overlayRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
99− }
100− onLoaded: {
101− item.source = image;
102− item.pressed = Qt.binding(function() { return root.pressed; });
103− }
104
88
105− Image {
89+ image: Image {
106 id: image
90 id: image
107 objectName: "image"
91 objectName: "image"
108
92
109 property url nextSource
93 property url nextSource
110 property string format: image.implicitWidth > image.implicitHeight ? "landscape" : "portrait"
94 property string format: image.implicitWidth > image.implicitHeight ? "landscape" : "portrait"
111
95
112− anchors.fill: parent
113− visible: !useUbuntuShape
114 fillMode: Image.PreserveAspectFit
96 fillMode: Image.PreserveAspectFit
115 asynchronous: true
97 asynchronous: true
116 cache: false
98 cache: false
99+ horizontalAlignment: Image.AlignHCenter
100+ verticalAlignment: Image.AlignVCenter
117 sourceSize.width: root.scaleTo == "width" ? root.width
101 sourceSize.width: root.scaleTo == "width" ? root.width
118− : root.scaleTo == "fit" && root.width <= root.height ? root.width
102+ : root.scaleTo == "fit" && root.width < root.height ? root.width
119 : 0
103 : 0
120 sourceSize.height: root.scaleTo == "height" ? root.height
104 sourceSize.height: root.scaleTo == "height" ? root.height
121− : root.scaleTo == "fit" && root.height <= root.width ? root.height
105+ : root.scale == "fit" && root.height < root.width ? root.height
122 : 0
106 : 0
123 }
107 }
124 }
108 }
@@ -171,7 +155,6 @@ Item {
171 easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
155 easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
172 }
156 }
173 }
157 }
174− ScriptAction { script: { lastScaledDimension = scaleTo == "height" || scaleTo == "fit" ? root.width : root.height } }
175 }
158 }
176 },
159 },
177
160
Components/ListItems/Base.qmlnew file+125
@@ -0,0 +1,125 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+AbstractButton {
21+ id: emptyListItem
22+ width: parent ? parent.width : units.gu(31)
23+ height: body.height + bottomDividerLine.height
24+
25+ /*!
26+ \preliminary
27+ Specifies whether the list item is selected.
28+ */
29+ property bool selected: false
30+
31+ /*!
32+ \preliminary
33+ Highlight the list item when it is pressed.
34+ This is used to disable the highlighting of the full list item
35+ when custom highlighting needs to be implemented (for example in
36+ ListItem.Standard which can have a split).
37+ */
38+ property bool highlightWhenPressed: true
39+
40+ /*!
41+ \preliminary
42+ Set to show or hide the thin bottom divider line (drawn by the \l ThinDivider component).
43+ This line is shown by default except in cases where this item is the delegate of a ListView.
44+ */
45+ property bool showDivider: __showDivider()
46+
47+ /*!
48+ \internal
49+ Method to automatically determine if the bottom divider line should be drawn.
50+ This always returns true, unless item is a delegate in a ListView. If in a ListView
51+ it will return false only when:
52+ + if this is the final item in the list, and ListView.footer is set (again as thin
53+ divider line won't look well with footer below it)
54+ */
55+ function __showDivider() {
56+ // if we're not in ListView, always show a thin dividing line at the bottom
57+ var model = null;
58+ if (typeof ListViewWithPageHeader !== 'undefined') {
59+ if (typeof ListViewWithPageHeader.model !== 'undefined') {
60+ model = ListViewWithPageHeader.model;
61+ }
62+ } else if (ListView.view !== null) {
63+ model = ListView.view.model;
64+ }
65+ // if we're last item in ListView don't show divider
66+ if (model && index === model.count - 1) return false;
67+
68+ return true;
69+ }
70+
71+ /* Relevant really only for ListViewWithPageHeader case: specify how many pixels we can overlap with the section header */
72+ readonly property int allowedOverlap: units.dp(1)
73+
74+ property real __heightToClip: {
75+ // Check this is in position where clipping is needed
76+ if (typeof ListViewWithPageHeader !== 'undefined') {
77+ if (typeof heightToClip !== 'undefined') {
78+ if (heightToClip >= allowedOverlap) {
79+ return heightToClip - allowedOverlap;
80+ }
81+ }
82+ }
83+ return 0;
84+ }
85+
86+ /*!
87+ \internal
88+ Reparent so that the visuals of the children does not
89+ occlude the bottom divider line.
90+ */
91+ default property alias children: body.children
92+
93+ Item {
94+ id: clippingContainer
95+ height: parent.height - __heightToClip
96+ anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
97+ clip: __heightToClip > 0
98+
99+ Item {
100+ id: body
101+ anchors {
102+ left: parent.left
103+ right: parent.right
104+ bottom: bottomDividerLine.top
105+ }
106+ height: childrenRect.height
107+ }
108+
109+ ThinDivider {
110+ id: bottomDividerLine
111+ anchors.bottom: parent.bottom
112+ visible: showDivider
113+ }
114+
115+ Highlight {
116+ anchors {
117+ top: parent.top
118+ left: parent.left
119+ right: parent.right
120+ bottom: bottomDividerLine.top
121+ }
122+ pressed: (emptyListItem.selected || (emptyListItem.highlightWhenPressed && emptyListItem.pressed)) ? "pressed" : ""
123+ }
124+ }
125+}
Components/ListItems/Header.qmlnew file+84
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ /*!
22+ \preliminary
23+ The text that is shown as the header text.
24+ \qmlproperty string text
25+ */
26+ property alias text: label.text
27+ property alias image: image.source
28+
29+ signal clicked(variant mouse)
30+
31+ height: units.gu(5)
32+
33+ Item {
34+ anchors {
35+ left: parent.left
36+ right: parent.right
37+ rightMargin: units.gu(0.5)
38+ top: parent.top
39+ bottom: bottomBorder.top
40+ }
41+
42+ Label {
43+ id: label
44+ anchors {
45+ left: parent.left
46+ leftMargin: units.gu(2)
47+ verticalCenter: parent.verticalCenter
48+ }
49+
50+ color: Theme.palette.selected.backgroundText //at 60%
51+ opacity: 0.6
52+ font.family: "Ubuntu"
53+ fontSize: "medium"
54+ elide: Text.ElideRight
55+ textFormat: Text.PlainText
56+ style: Text.Raised
57+ styleColor: "black"
58+ width: parent.width - image.width - image.leftMargin - anchors.leftMargin
59+ }
60+
61+ Image {
62+ id: image
63+ readonly property double leftMargin: units.gu(1)
64+ x: label.x + label.contentWidth + leftMargin
65+ anchors {
66+ verticalCenter: parent.verticalCenter
67+ }
68+ }
69+ }
70+
71+ ThinDivider {
72+ id: bottomBorder
73+ anchors {
74+ left: parent.left
75+ right: parent.right
76+ bottom: parent.bottom
77+ }
78+ }
79+
80+ MouseArea {
81+ anchors.fill: parent
82+ onClicked: parent.clicked(mouse)
83+ }
84+}
Components/ListItems/Highlight.qmlnew file+46
@@ -0,0 +1,46 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+Rectangle {
20+ id: highlight
21+
22+ property bool pressed: false
23+ property real pressedOpacity: 0.3
24+
25+ color: "black"
26+ opacity: 0
27+ state: pressed ? "pressed" : ""
28+ states: [
29+ State {
30+ name: "pressed"
31+ PropertyChanges { target: highlight; opacity: pressedOpacity}
32+ }
33+ ]
34+ transitions: [
35+ Transition {
36+ from: ""
37+ to: "pressed"
38+ NumberAnimation { target: highlight; property: "opacity"; duration: 50}
39+ },
40+ Transition {
41+ from: "pressed"
42+ to: ""
43+ NumberAnimation { target: highlight; property: "opacity"; duration: 100}
44+ }
45+ ]
46+}
Components/ListItems/ThinDivider.qmlnew file+27
@@ -0,0 +1,27 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+Image {
20+ anchors {
21+ left: (parent) ? parent.left : null
22+ right: (parent) ? parent.right : null
23+ }
24+ height: (visible) ? units.dp(2) : 0
25+
26+ source: "graphics/ListItemDividerHorizontal.png"
27+}
tests/qmltests/Components/tst_EdgeDragEvaluator.qml → Components/ListItems/VerticalThinDivider.qmlrenamed+8−9
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2012 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,14 +14,13 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import "../../../qml/Components"
19
18
20−Item {
19+Image {
21− width: units.gu(70)
20+ anchors {
22− height: units.gu(70)
21+ top: (parent) ? parent.top : null
23−
22+ bottom: (parent) ? parent.bottom : null
24− EdgeDragEvaluator {
25− objectName: "edgeDragEvaluator"
26 }
23 }
24+ width: (visible) ? units.dp(2) : 0
25+ source: "graphics/ListItemDividerVertical.png"
27}
26}
Components/ListItems/graphics/ListItemDividerHorizontal@18.pngnew file

Binary file not shown.

Components/ListItems/graphics/ListItemDividerVertical@18.pngnew file

Binary file not shown.

qml/Wizard/WizardTextField.qml → Components/Math.jsrenamed+8−7
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015-2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,12 +14,13 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+.pragma library
18−import Ubuntu.Components 1.3
19−import Ubuntu.Components.Themes.Ambiance 1.3
20
18
21−TextField {
19+function clamp(value, min, max) {
22− id: styledItem
20+ if (min <= max) {
23− style: TextFieldStyle {
21+ return Math.max(min, Math.min(max, value))
22+ } else {
23+ // swap min/max if min > max
24+ return clamp(value, max, min)
24 }
25 }
25}
26}
Components/OpenEffect.qmlnew file+138
@@ -0,0 +1,138 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+Item {
20+ id: effect
21+ property bool enabled: topGapPx != positionPx || bottomGapPx != positionPx
22+ property alias live: effectSource.live
23+ property Item sourceItem
24+ property ShaderEffectSource source: ShaderEffectSource {
25+ id: effectSource
26+ sourceItem: effect.enabled ? effect.sourceItem : null
27+ hideSource: effect.enabled
28+ live: false
29+ sourceRect: {
30+ if (effect.enabled) {
31+ Qt.rect(0, -effect.topOverflow, sourceItem.width, sourceItem.height + effect.topOverflow + effect.bottomOverflow)
32+ } else {
33+ Qt.rect(0, 0, 0, 0)
34+ }
35+ }
36+ }
37+
38+ onEnabledChanged: if (!live && enabled) scheduleUpdate()
39+
40+ /*!
41+ \qmlproperty real positionPx
42+ The y coordinate of where to perform the split.
43+
44+ \qmlproperty real topGapPx
45+ Gap's top edge.
46+
47+ \qmlproperty real bottomGapPx
48+ Gap's bottom edge.
49+
50+ \qmlproperty real topOverflow
51+ How much of the sourceItem should be sourced above its bounds.
52+
53+ \qmlproperty real bottomOverflow
54+ How much of the sourceItem should be sourced below its bounds.
55+ */
56+
57+ property real positionPx: 0
58+ property real topGapPx: 0
59+ property real bottomGapPx: height
60+ property real topOverflow: 0.0
61+ property real bottomOverflow: 0.0
62+ property real topOpacity: 1.0
63+ property real bottomOpacity: 1.0
64+
65+ property real __roundedPositionPx: Math.round(positionPx)
66+
67+ function scheduleUpdate() {
68+ source.scheduleUpdate();
69+ }
70+
71+ ShaderEffect {
72+ id: top
73+ visible: effect.enabled
74+ opacity: topOpacity
75+ property ShaderEffectSource source: effect.source
76+ property real positionPx: __roundedPositionPx
77+ property real factor: effect.height / height
78+
79+ clip: true
80+
81+ anchors {
82+ top: parent.top
83+ left: parent.left
84+ right: parent.right
85+ topMargin: -topOverflow - positionPx + topGapPx
86+ }
87+ height: topOverflow + positionPx
88+
89+ vertexShader: "
90+ uniform highp mat4 qt_Matrix;
91+ attribute highp vec4 qt_Vertex;
92+ attribute highp vec2 qt_MultiTexCoord0;
93+ varying highp vec2 qt_TexCoord0;
94+ uniform highp float factor;
95+
96+ void main() {
97+ highp vec4 pos = qt_Vertex;
98+ pos.y *= factor;
99+ gl_Position = qt_Matrix * pos;
100+ qt_TexCoord0 = qt_MultiTexCoord0;
101+ }
102+ "
103+ }
104+
105+ ShaderEffect {
106+ id: bottom
107+ visible: effect.enabled
108+ opacity: bottomOpacity
109+ property ShaderEffectSource source: effect.source
110+ property real offset: effect.topOverflow + __roundedPositionPx
111+ property real factor: effect.height / height
112+
113+ clip: true
114+
115+ anchors {
116+ left: parent.left
117+ right: parent.right
118+ }
119+ y: topOverflow + bottomGapPx
120+ height: sourceItem.height - positionPx + bottomOverflow
121+
122+ vertexShader: "
123+ uniform highp mat4 qt_Matrix;
124+ attribute highp vec4 qt_Vertex;
125+ attribute highp vec2 qt_MultiTexCoord0;
126+ varying highp vec2 qt_TexCoord0;
127+ uniform highp float factor;
128+ uniform highp float offset;
129+
130+ void main() {
131+ highp vec4 pos = qt_Vertex;
132+ pos.y = (pos.y * factor) - offset;
133+ gl_Position = qt_Matrix * pos;
134+ qt_TexCoord0 = qt_MultiTexCoord0;
135+ }
136+ "
137+ }
138+}
Components/PageHeader.qmlnew file+392
@@ -0,0 +1,392 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.Popups 0.1
20+import Ubuntu.Components.ListItems 0.1 as ListItem
21+import Unity 0.1
22+
23+Item {
24+ /*!
25+ \preliminary
26+ The text that is shown inside the Page Header
27+ \qmlproperty string text
28+ */
29+ property alias text: label.text
30+
31+ property bool searchEntryEnabled: false
32+ property alias searchQuery: searchField.text
33+ property ListModel searchHistory: SearchHistoryModel {}
34+ property Scope scope
35+
36+ height: units.gu(8.5)
37+ implicitHeight: units.gu(8.5)
38+
39+ function triggerSearch() {
40+ if (searchEntryEnabled) searchField.forceActiveFocus()
41+ }
42+
43+ function resetSearch() {
44+ if (!searchHistory) return;
45+
46+ searchHistory.addQuery(searchField.text);
47+ searchField.text = "";
48+ searchField.focus = false;
49+ }
50+
51+ function unfocus() {
52+ searchField.focus = false;
53+ }
54+
55+ Connections {
56+ target: greeter
57+ onShownChanged: if (shown) resetSearch()
58+ }
59+
60+ Flickable {
61+ id: header
62+ anchors {
63+ left: parent.left
64+ right: parent.right
65+ top: parent.top
66+ }
67+ height: units.gu(6.5)
68+
69+ interactive: false
70+ contentHeight: headerContainer.height
71+ clip: true
72+
73+ contentY: searchField.activeFocus || searchField.text != "" ? searchContainer.y : headerContainer.y
74+
75+ Behavior on contentY { NumberAnimation { duration: 200; easing.type: Easing.OutQuad } }
76+
77+ // FIXME this could potentially be simplified to avoid all the containers
78+ Item {
79+ id: headerContainer
80+
81+ width: parent.width
82+ height: childrenRect.height
83+
84+ Item {
85+ id: textContainer
86+
87+ width: header.width
88+ height: header.height
89+
90+ Label {
91+ id: label
92+ anchors {
93+ left: parent.left
94+ leftMargin: units.gu(2)
95+ right: parent.right
96+ verticalCenter: parent.verticalCenter
97+ }
98+
99+ color: Theme.palette.selected.backgroundText
100+ opacity: 0.8
101+ font.family: "Ubuntu"
102+ font.weight: Font.Light
103+ fontSize: "x-large"
104+ elide: Text.ElideRight
105+ style: Text.Raised
106+ styleColor: "black"
107+ }
108+ }
109+
110+ Item {
111+ id: searchContainer
112+ objectName: "searchContainer"
113+
114+ visible: searchEntryEnabled
115+
116+ property bool narrowMode: parent.width < label.contentWidth + units.gu(50)
117+
118+ property bool active: searchField.text != "" || searchField.activeFocus
119+ property var popover: null
120+
121+ anchors.right: textContainer.right
122+ height: header.height
123+
124+ state:
125+ if (active && narrowMode) "narrowActive"
126+ else if (!active && narrowMode) "narrowInactive"
127+ else if (active && !narrowMode) "active"
128+ else if (!active && !narrowMode) "inactive"
129+
130+ function openPopover() {
131+ if (searchHistory.count > 0) {
132+ searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
133+ {
134+ "pointerTarget": pointerPositioner,
135+ "contentWidth": searchField.width,
136+ "edgeMargins": units.gu(1)
137+ }
138+ )
139+ }
140+ }
141+
142+ function closePopover() {
143+ if (searchContainer.popover) PopupUtils.close(searchContainer.popover)
144+ }
145+
146+ onActiveFocusChanged: if (!activeFocus) { searchHistory.addQuery(searchField.text) }
147+
148+ TextField {
149+ id: searchField
150+
151+ anchors.fill: parent
152+ anchors.margins: units.gu(1)
153+
154+ hasClearButton: false
155+
156+ primaryItem: AbstractButton {
157+ enabled: searchField.text != "" && !searchIndicator.running
158+ onClicked: {
159+ if (searchField.text != "") {
160+ searchHistory.addQuery(searchField.text)
161+ searchField.text = ""
162+ }
163+ }
164+ height: parent.height
165+ width: height
166+
167+ ActivityIndicator {
168+ id: searchIndicator
169+ objectName: "searchIndicator"
170+
171+ anchors {
172+ verticalCenter: parent.verticalCenter
173+ left: parent.left
174+ leftMargin: units.gu(0.5)
175+ }
176+
177+ running: opacity > 0
178+ }
179+
180+ Image {
181+ id: primaryImage
182+ objectName: "primaryImage"
183+ anchors {
184+ verticalCenter: parent.verticalCenter
185+ left: parent.left
186+ leftMargin: units.gu(0.5)
187+ }
188+ width: units.gu(3)
189+ height: units.gu(3)
190+ visible: opacity > 0
191+ }
192+
193+ Item {
194+ id: pointerPositioner
195+ anchors.left: parent.right
196+ anchors.leftMargin: units.gu(0.5)
197+ anchors.top: parent.bottom
198+ }
199+ }
200+
201+ onTextChanged: {
202+ if (text != "") searchContainer.closePopover()
203+ else if (text == "" && activeFocus) searchContainer.openPopover()
204+ }
205+
206+ onActiveFocusChanged: {
207+ if (!activeFocus) searchContainer.closePopover()
208+ }
209+
210+ states: [
211+ State {
212+ name: "searching"
213+ when: scope && scope.searchInProgress
214+ PropertyChanges { target: searchIndicator; running: true; opacity: 1 }
215+ PropertyChanges { target: primaryImage; opacity: 0 }
216+ },
217+ State {
218+ name: "idle"
219+ when: !scope || !scope.searchInProgress
220+ PropertyChanges { target: searchIndicator; opacity: 0 }
221+ PropertyChanges { target: primaryImage; opacity: 1 }
222+ }
223+ ]
224+
225+ transitions: [
226+ Transition {
227+ to: "searching"
228+ reversible: true
229+ SequentialAnimation {
230+ NumberAnimation { target: primaryImage; property: "opacity"; duration: UbuntuAnimation.FastDuration; easing.type: Easing.Linear }
231+ NumberAnimation { target: searchIndicator; property: "opacity"; duration: UbuntuAnimation.FastDuration; easing.type: Easing.Linear }
232+ }
233+ }
234+ ]
235+ }
236+
237+ states: [
238+ State {
239+ name: "wide"
240+ AnchorChanges { target: textContainer; anchors.top: headerContainer.top }
241+ AnchorChanges { target: searchContainer; anchors.left: undefined; anchors.top: textContainer.top }
242+ },
243+ State {
244+ name: "narrow"
245+ PropertyChanges { target: searchField; highlighted: true }
246+ AnchorChanges { target: textContainer; anchors.top: searchContainer.bottom }
247+ AnchorChanges { target: searchContainer; anchors.left: headerContainer.left; anchors.top: headerContainer.top }
248+ },
249+ State {
250+ name: "active"
251+ extend: "wide"
252+ PropertyChanges { target: searchContainer; width: units.gu(40) }
253+ PropertyChanges { target: primaryImage; source: searchField.text ? "../Dash/graphics/icon_clear.png" : "../Dash/graphics/icon_search_active.png" }
254+ PropertyChanges { target: searchField; highlighted: true }
255+ },
256+ State {
257+ name: "inactive"
258+ extend: "wide"
259+ PropertyChanges { target: searchContainer; width: units.gu(25) }
260+ PropertyChanges { target: primaryImage; source: "../Dash/graphics/icon_search_inactive.png" }
261+ PropertyChanges { target: searchField; highlighted: false }
262+ },
263+ State {
264+ name: "narrowActive"
265+ extend: "narrow"
266+ PropertyChanges { target: header; contentY: 0 }
267+ PropertyChanges { target: primaryImage; source: searchField.text ? "../Dash/graphics/icon_clear.png" : "../Dash/graphics/icon_search_active.png" }
268+ },
269+ State {
270+ name: "narrowInactive"
271+ extend: "narrow"
272+ PropertyChanges { target: header; contentY: header.height }
273+ PropertyChanges { target: primaryImage; source: searchField.text ? "../Dash/graphics/icon_clear.png" : "../Dash/graphics/icon_search_active.png" }
274+ }
275+ ]
276+
277+ transitions: [
278+ Transition {
279+ to: "active"
280+ SequentialAnimation {
281+ ParallelAnimation {
282+ NumberAnimation { targets: [searchContainer, searchField]; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
283+ PropertyAction { target: primaryImage; property: "source" }
284+ AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
285+ }
286+ ScriptAction { script: searchContainer.openPopover() }
287+ }
288+ },
289+ Transition {
290+ to: "inactive"
291+ ScriptAction { script: searchContainer.closePopover() }
292+ NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
293+ AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
294+ },
295+ Transition {
296+ to: "narrowActive"
297+ SequentialAnimation {
298+ ParallelAnimation {
299+ NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
300+ AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
301+ }
302+ ScriptAction { script: searchContainer.openPopover() }
303+ }
304+ },
305+ Transition {
306+ to: "narrowInactive"
307+ ScriptAction { script: searchContainer.closePopover() }
308+ NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
309+ AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
310+ }
311+ ]
312+
313+ Component {
314+ id: popoverComponent
315+ Popover {
316+ id: popover
317+
318+ // FIXME: this should go into the first item below, but enable: false
319+ // prevents mouse events propagation
320+ AbstractButton {
321+ anchors {
322+ top: parent.top
323+ right: parent.right
324+ }
325+ height: units.gu(6)
326+ width: height
327+
328+ onClicked: searchContainer.closePopover()
329+
330+ Image {
331+ anchors.centerIn: parent
332+ width: units.gu(2)
333+ height: units.gu(2)
334+ source: "../Dash/graphics/icon_listview_clear.png"
335+ }
336+ }
337+
338+ Column {
339+ anchors {
340+ top: parent.top
341+ left: parent.left
342+ right: parent.right
343+ }
344+
345+ ListItem.Standard { enabled: false; text: i18n.tr("Recent searches") }
346+
347+ Repeater {
348+ id: recentSearches
349+ model: searchHistory
350+
351+ delegate: ListItem.Standard {
352+ showDivider: index < recentSearches.count - 1
353+ text: query
354+ onClicked: {
355+ searchHistory.addQuery(text)
356+ searchField.text = text
357+ }
358+ }
359+ }
360+ }
361+ }
362+ }
363+
364+ InverseMouseArea {
365+ enabled: searchField.activeFocus
366+
367+ anchors {
368+ top: parent.top
369+ left: parent.left
370+ right: parent.right
371+ }
372+
373+ height: searchContainer.popover ? parent.height + searchContainer.popover.contentHeight + units.gu(2) : parent.height
374+
375+ onPressed: searchField.focus = false
376+ }
377+ }
378+ }
379+ }
380+
381+ BorderImage {
382+ id: bottomBorder
383+ anchors {
384+ top: header.bottom
385+ left: parent.left
386+ right: parent.right
387+ bottom: parent.bottom
388+ }
389+
390+ source: "graphics/PageHeaderBaseDivider.sci"
391+ }
392+}
tests/qmltests/Components/tst_DragHandle/SimpleButton.qml → Components/PinPadButton.qmlrenamed+23−11
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,21 +14,33 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19
19
20−
20+Item {
21−Rectangle {
22 id: root
21 id: root
22+
23− property alias text: textItem.text
23+ property alias text: label.text
24+ property alias iconName: icon.name
25+
24 signal clicked()
26 signal clicked()
25− width: textItem.width + units.gu(1.5)
27+
26− height: textItem.height + units.gu(1.5)
28+ Label {
27− Text {
29+ id: label
28− id: textItem
29 anchors.centerIn: parent
30 anchors.centerIn: parent
30− font.pixelSize: units.gu(1.5)
31+ color: "#f3f3e7"
32+ fontSize: "large"
33+ font.weight: Font.DemiBold
31 }
34 }
35+
36+ Icon {
37+ id: icon
38+ height: units.gu(3)
39+ width: height
40+ anchors.centerIn: parent
41+ color: "#f3f3e7"
42+ }
43+
32 MouseArea {
44 MouseArea {
33 anchors.fill: parent
45 anchors.fill: parent
34 onClicked: root.clicked()
46 onClicked: root.clicked()
Components/RatingStars.qmlnew file+41
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+Row {
20+ id: root
21+ property int rating
22+ property int maximumRating: 5
23+ property int starCount: 5
24+ height: childrenRect.height
25+ width: childrenRect.width
26+
27+ readonly property int effectiveRating: Math.max(0, Math.min(root.starCount * root.rating / root.maximumRating, root.maximumRating))
28+
29+ Repeater {
30+ model: root.effectiveRating
31+ Image {
32+ source: "graphics/icon_star_on.png"
33+ }
34+ }
35+ Repeater {
36+ model: root.starCount - root.effectiveRating
37+ Image {
38+ source: "graphics/icon_star_off.png"
39+ }
40+ }
41+}
Components/ResponsiveFlowView.qmlnew file+81
@@ -0,0 +1,81 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: root
22+
23+ property int minimumHorizontalSpacing: units.gu(0.5)
24+ // property int minimumNumberOfColumns: 2 // FIXME: not implemented
25+ property int maximumNumberOfColumns: 6
26+ readonly property int columns: flow.columns
27+ property alias verticalSpacing: flow.verticalSpacing
28+ property alias horizontalSpacing: flow.horizontalSpacing
29+ property int referenceDelegateWidth
30+ property alias firstModel: repeater1.model
31+ property alias secondModel: repeater2.model
32+ property alias delegate: repeater1.delegate
33+ readonly property int cellWidth: referenceDelegateWidth + horizontalSpacing
34+ readonly property int cellHeight: referenceDelegateWidth + verticalSpacing
35+ property alias move: flow.move
36+
37+ height: flow.height + flow.anchors.topMargin
38+
39+ Flow {
40+ id: flow
41+ anchors {
42+ left: parent.left
43+ right: parent.right
44+ top: parent.top
45+ leftMargin: margin/2
46+ rightMargin: margin/2
47+ topMargin: verticalSpacing
48+ }
49+
50+ function pixelToGU(value) {
51+ return Math.floor(value / units.gu(1));
52+ }
53+
54+ function spacingForColumns(columns) {
55+ // spacing between columns as an integer number of GU, the remainder goes in the margins
56+ var spacingGU = pixelToGU(allocatableVerticalSpace / columns);
57+ return units.gu(spacingGU);
58+ }
59+
60+ function columnsForSpacing(space) {
61+ // minimum margin is half of the spacing
62+ return Math.floor((parent.width - space/2) / (referenceDelegateWidth + space));
63+ }
64+
65+ property real allocatableVerticalSpace: parent.width - columns * referenceDelegateWidth
66+ property int columns: Math.min(columnsForSpacing(minimumHorizontalSpacing), maximumNumberOfColumns)
67+ property real horizontalSpacing: spacingForColumns(columns)
68+ property real verticalSpacing: horizontalSpacing
69+ property int margin: allocatableVerticalSpace - columns * horizontalSpacing
70+
71+ Repeater {
72+ id: repeater1
73+ model: (root.model) ? root.model[0] : null
74+ }
75+ Repeater {
76+ id: repeater2
77+ model: (root.model) ? root.model[1] : null
78+ delegate: repeater1.delegate
79+ }
80+ }
81+}
Components/ResponsiveGridView.qmlnew file+94
@@ -0,0 +1,94 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+/*
21+ Essentially a GridView where you can specify the maximum number of columns it can have.
22+ */
23+Item {
24+ property int minimumHorizontalSpacing: units.gu(0.5)
25+ // property int minimumNumberOfColumns: 2 // FIXME: not implemented
26+ property int maximumNumberOfColumns: 6
27+ readonly property int columns: gridView.columns
28+ property alias verticalSpacing: gridView.verticalSpacing
29+ readonly property alias margins: gridView.margin
30+ property int delegateWidth
31+ property int delegateHeight
32+ property alias model: gridView.model
33+ property alias delegate: gridView.delegate
34+ readonly property int cellWidth: gridView.cellWidth
35+ readonly property int cellHeight: gridView.cellHeight
36+ readonly property int totalContentHeight: {
37+ return contentHeightForRows(Math.ceil(gridView.model.count / columns))
38+ }
39+ property alias interactive: gridView.interactive
40+ readonly property alias flicking: gridView.flicking
41+ readonly property alias moving: gridView.moving
42+ readonly property alias pressDelay: gridView.pressDelay
43+ property alias delegateCreationBegin: gridView.delegateCreationBegin
44+ property alias delegateCreationEnd: gridView.delegateCreationEnd
45+ property alias highlightIndex: gridView.highlightIndex
46+ readonly property alias currentItem: gridView.currentItem
47+
48+ function contentHeightForRows(rows) {
49+ return rows * cellHeight + verticalSpacing
50+ }
51+
52+ GridView {
53+ id: gridView
54+ objectName: "responsiveGridViewGrid"
55+ anchors {
56+ fill: parent
57+ leftMargin: margin/2
58+ rightMargin: margin/2
59+ topMargin: verticalSpacing
60+ }
61+ clip: parent.height != totalContentHeight
62+
63+ function pixelToGU(value) {
64+ return Math.floor(value / units.gu(1));
65+ }
66+
67+ function spacingForColumns(columns) {
68+ // spacing between columns as an integer number of GU, the remainder goes in the margins
69+ var spacingGU = pixelToGU(allocatableHorizontalSpace / columns);
70+ return units.gu(spacingGU);
71+ }
72+
73+ function columnsForSpacing(spacing) {
74+ // minimum margin is half of the spacing
75+ return Math.max(1, Math.floor((parent.width - spacing/2) / (delegateWidth + spacing)));
76+ }
77+
78+ property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
79+ property int columns: Math.min(columnsForSpacing(minimumHorizontalSpacing), maximumNumberOfColumns)
80+ property real horizontalSpacing: spacingForColumns(columns)
81+ property real verticalSpacing: horizontalSpacing
82+ property int margin: allocatableHorizontalSpace - columns * horizontalSpacing
83+ property int highlightIndex: -1
84+
85+ cellWidth: delegateWidth + horizontalSpacing
86+ cellHeight: delegateHeight + verticalSpacing
87+
88+ onHighlightIndexChanged: {
89+ if (highlightIndex != -1) {
90+ currentIndex = highlightIndex
91+ }
92+ }
93+ }
94+}
Components/Revealer.qmlnew file+242
@@ -0,0 +1,242 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "Math.js" as MathLocal
20+
21+Item {
22+ id: revealer
23+
24+ property Showable target
25+ property var hintingAnimation: hintingAnimation
26+ property string boundProperty: orientation == Qt.Vertical ? "y" : "x"
27+ property int orientation: Qt.Vertical
28+ property int direction: Qt.LeftToRight
29+ property real openedValue: orientation == Qt.Vertical ? y : x
30+ property real closedValue: orientation == Qt.Vertical ? y + (direction == Qt.LeftToRight ? -height : height) : x + (direction == Qt.LeftToRight ? -width : width)
31+ property real hintDisplacement: 0
32+ property real handleSize: units.gu(2)
33+ property real dragVelocity: draggingArea.dragVelocity != 0 ? Math.abs(draggingArea.dragVelocity) : -1
34+ property real dragVelocityThreshold: units.gu(5)
35+ property bool dragging: false
36+ property bool pressed: draggingArea.pressed
37+ property int lateralPosition: draggingArea.lateralPosition
38+ property real dragPosition
39+ property bool openOnPress: true
40+
41+ signal openPressed(int mouseX, int mouseY)
42+ signal openReleased(int mouseX, int mouseY)
43+ signal closePressed
44+ signal openClicked
45+ signal closeClicked
46+
47+ dragPosition: {
48+ var value
49+ if (orientation == Qt.Vertical) {
50+ value = draggingArea.dragValue + draggingArea.y
51+ if (direction == Qt.RightToLeft) {
52+ value += draggingArea.height - height
53+ }
54+ } else {
55+ value = draggingArea.dragValue + draggingArea.x
56+ if (direction == Qt.RightToLeft) {
57+ value += draggingArea.width - width
58+ }
59+ }
60+ if (__opened) {
61+ if (direction == Qt.LeftToRight) {
62+ value += handleSize
63+ } else {
64+ value -= handleSize
65+ }
66+ } else if (dragging) {
67+ if (direction == Qt.LeftToRight) {
68+ value += hintDisplacement
69+ } else {
70+ value -= hintDisplacement
71+ }
72+ }
73+
74+ return value
75+ }
76+ property var draggingArea: leftDraggingArea.enabled ? leftDraggingArea : rightDraggingArea
77+
78+ property real __hintValue: closedValue + (direction == Qt.LeftToRight ? hintDisplacement : -hintDisplacement)
79+
80+ function dragToValue(dragPosition) {
81+ return dragPosition + closedValue
82+ }
83+
84+ property bool __opened: target.shown
85+ enabled: target.available
86+
87+ // Can be replaced with a fake implementation during tests
88+ // property var __getCurrentTimeMs: function () { return new Date().getTime() }
89+ property var __dateTime: new function() {
90+ this.getCurrentTimeMs = function() {return new Date().getTime()}
91+ }
92+
93+ Component.onCompleted: target[boundProperty] = __opened ? openedValue : closedValue
94+ onOpenedValueChanged: if (__opened && !dragging) target[boundProperty] = openedValue
95+ onClosedValueChanged: if (!__opened && !dragging) target[boundProperty] = closedValue
96+
97+ function __computeValue(dragPosition) {
98+ return MathLocal.clamp(dragToValue(dragPosition), __hintValue, openedValue)
99+ }
100+
101+ function __open() {
102+ hintingAnimation.stop()
103+ target.show()
104+ }
105+
106+ function __close() {
107+ hintingAnimation.stop()
108+ target.hide()
109+ }
110+
111+ function __hint() {
112+ target.showAnimation.stop()
113+ target.hideAnimation.stop()
114+ hintingAnimation.restart()
115+ }
116+
117+ function __settle() {
118+ hintingAnimation.stop()
119+ if (__opened) target.show()
120+ else target.hide()
121+ }
122+
123+ function __startDragging() {
124+ hintingAnimation.stop()
125+ dragging = true
126+ }
127+
128+ function __endDragging(dragVelocity) {
129+ dragging = false
130+ if (revealer.direction == Qt.RightToLeft) {
131+ dragVelocity = -dragVelocity
132+ }
133+ if (Math.abs(dragVelocity) >= dragVelocityThreshold) {
134+ if (dragVelocity > 0) __open()
135+ else __close()
136+ } else {
137+ __settle()
138+ }
139+ }
140+
141+ Binding {
142+ id: dragBinding
143+
144+ target: revealer.target
145+ property: revealer.boundProperty
146+ value: __computeValue(dragPosition)
147+ when: dragging
148+ }
149+
150+ SmoothedAnimation {
151+ id: hintingAnimation
152+
153+ target: revealer.target
154+ property: revealer.boundProperty
155+ duration: 150
156+ to: revealer.__hintValue
157+ }
158+
159+ DraggingArea {
160+ id: leftDraggingArea
161+
162+ property bool isOpeningArea: revealer.direction == Qt.LeftToRight
163+
164+ height: orientation == Qt.Vertical ? handleSize : parent.height
165+ width: orientation == Qt.Horizontal ? handleSize : parent.width
166+ orientation: revealer.orientation
167+ enabled: isOpeningArea ? !revealer.__opened : revealer.__opened
168+
169+ __dateTime: revealer.__dateTime
170+
171+ onPressed: {
172+ if (isOpeningArea) {
173+ if (revealer.openOnPress) {
174+ revealer.openPressed(mouseX, mouseY)
175+ __hint()
176+ }
177+ } else {
178+ revealer.closePressed()
179+ }
180+ }
181+ onReleased: {
182+ if (isOpeningArea && revealer.openOnPress) {
183+ revealer.openReleased(mouseX, mouseY)
184+ __settle()
185+ }
186+ }
187+ onDragStart: __startDragging()
188+ onDragEnd: __endDragging(dragVelocity)
189+ onClicked: {
190+ if (clickValidated) {
191+ if (isOpeningArea) {
192+ if (revealer.openOnPress) revealer.openClicked()
193+ } else {
194+ revealer.closeClicked()
195+ }
196+ }
197+ }
198+ }
199+
200+ DraggingArea {
201+ id: rightDraggingArea
202+
203+ property bool isOpeningArea: revealer.direction == Qt.RightToLeft
204+
205+ x: orientation == Qt.Vertical ? 0 : parent.width - width
206+ y: orientation == Qt.Vertical ? parent.height - height : 0
207+ height: orientation == Qt.Vertical ? handleSize : parent.height
208+ width: orientation == Qt.Horizontal ? handleSize : parent.width
209+ orientation: revealer.orientation
210+ enabled: isOpeningArea ? !revealer.__opened : revealer.__opened
211+
212+ __dateTime: revealer.__dateTime
213+
214+ onPressed: {
215+ if (isOpeningArea) {
216+ if (revealer.openOnPress) {
217+ revealer.openPressed(mouseX, mouseY)
218+ __hint()
219+ }
220+ } else {
221+ revealer.closePressed()
222+ }
223+ }
224+ onReleased: {
225+ if (isOpeningArea && revealer.openOnPress) {
226+ revealer.openReleased(mouseX, mouseY)
227+ __settle()
228+ }
229+ }
230+ onDragStart: __startDragging()
231+ onDragEnd: __endDragging(dragVelocity)
232+ onClicked: {
233+ if (clickValidated) {
234+ if (isOpeningArea) {
235+ if (revealer.openOnPress) revealer.openClicked()
236+ } else {
237+ revealer.closeClicked()
238+ }
239+ }
240+ }
241+ }
242+}
qml/Components/SearchHistoryModel/SearchHistoryModel.qml → Components/SearchHistoryModel.qmlrenamed+1−2
@@ -14,8 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−pragma Singleton
18−import QtQuick 2.4
17+import QtQuick 2.0
19
18
20// TODO sanitize input, move to persistent storage
19// TODO sanitize input, move to persistent storage
21
20
qml/Components/Showable.qml → Components/Showable.qmlrenamed+11−37
@@ -1,6 +1,5 @@
1/*
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
2 * Copyright (C) 2013 Canonical, Ltd.
3− * Copyright (C) 2019 UBports Foundation
4 *
3 *
5 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -15,7 +14,7 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
15 */
17
16
18−import QtQuick 2.4
17+import QtQuick 2.0
19
18
20Item {
19Item {
21 id: showable
20 id: showable
@@ -32,16 +31,15 @@ Item {
32 property bool required
31 property bool required
33 property bool __shouldShow: false
32 property bool __shouldShow: false
34 property bool __skipShowAnimation: false
33 property bool __skipShowAnimation: false
35− property bool __skipHideAnimation: false
36
34
37 property list<QtObject> hides
35 property list<QtObject> hides
38− property Animation showAnimation
36+ property var showAnimation
39− property Animation hideAnimation
37+ property var hideAnimation
40
38
41 // automatically set the target on showAnimation and hideAnimation to be the
39 // automatically set the target on showAnimation and hideAnimation to be the
42 // showable itself
40 // showable itself
43− onShowAnimationChanged: if (showAnimation && showAnimation.hasOwnProperty("target")) showAnimation["target"] = showable
41+ onShowAnimationChanged: if (showAnimation) showAnimation["target"] = showable
44− onHideAnimationChanged: if (hideAnimation && hideAnimation.hasOwnProperty("target")) hideAnimation["target"] = showable
42+ onHideAnimationChanged: if (hideAnimation) hideAnimation["target"] = showable
45
43
46 Component.onCompleted: required = shown;
44 Component.onCompleted: required = shown;
47
45
@@ -74,9 +72,6 @@ Item {
74 }
72 }
75
73
76 function __reallyShow() {
74 function __reallyShow() {
77− if (showAnimation != undefined && showAnimation.running)
78− return;
79−
80 if (!available) {
75 if (!available) {
81 __skipShowAnimation = false;
76 __skipShowAnimation = false;
82 return false;
77 return false;
@@ -89,8 +84,10 @@ Item {
89 }
84 }
90
85
91 if (showAnimation != undefined) {
86 if (showAnimation != undefined) {
87+ if (!showAnimation.running) {
92− showAnimation.restart()
88+ showAnimation.restart()
89+ }
93− if (__skipShowAnimation || shown) {
90+ if (__skipShowAnimation) {
94 showAnimation.complete();
91 showAnimation.complete();
95 }
92 }
96 } else {
93 } else {
@@ -102,30 +99,13 @@ Item {
102 return true;
99 return true;
103 }
100 }
104
101
105− /*
106− Will be called right before starting the hideAnimation.
107− */
108− property var prepareToHide: function(){}
109−
110 function hide() {
102 function hide() {
111− if (hideAnimation != undefined && hideAnimation.running)
112− return;
113−
114 if (showAnimation != undefined && showAnimation.running) {
103 if (showAnimation != undefined && showAnimation.running) {
115 showAnimation.stop()
104 showAnimation.stop()
116 }
105 }
117−
118− if (typeof prepareToHide === "function") {
119− prepareToHide();
120− } else {
121− console.warn("Showable.prepareToHide should be a function, but it's a " +
122− (typeof prepareToHide) + " instead");
123− }
124−
125 if (hideAnimation != undefined) {
106 if (hideAnimation != undefined) {
126− hideAnimation.restart()
107+ if (!hideAnimation.running) {
127− if (__skipHideAnimation || !shown) {
128− hideAnimation.complete();
108+ hideAnimation.restart()
129 }
109 }
130 } else {
110 } else {
131 visible = false
111 visible = false
@@ -133,12 +113,6 @@ Item {
133 }
113 }
134
114
135 shown = false
115 shown = false
136− __skipHideAnimation = false;
137− }
138−
139− function hideNow() {
140− __skipHideAnimation = true;
141− hide();
142 }
116 }
143
117
144 Connections {
118 Connections {
Components/Stage.qmlnew file+562
@@ -0,0 +1,562 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Unity.Application 0.1
19+import Ubuntu.Components 0.1
20+import Ubuntu.Gestures 0.1
21+
22+/*
23+ Responsible for application switching.
24+
25+ Drag from the right edge to switch to the next application.
26+ While being dragged, this component will show an animation for the user to
27+ visualize that he's changing the stacking of applications (next/new app comes from
28+ right edge and current/old app fades out).
29+ */
30+Showable {
31+ id: stage
32+
33+ width: units.gu(40)
34+ height: units.gu(71)
35+
36+ property int type: ApplicationInfo.MainStage
37+ property var applicationManager
38+ readonly property var applications:
39+ type == ApplicationInfo.MainStage ? applicationManager.mainStageApplications
40+ : applicationManager.sideStageApplications
41+ property bool fullyShown: false
42+ property bool fullyHidden: true
43+ readonly property var focusedApplication:
44+ type == ApplicationInfo.MainStage ? applicationManager.mainStageFocusedApplication
45+ : applicationManager.sideStageFocusedApplication
46+ property bool shouldUseScreenshots: true
47+
48+ /* Will be true whenever application screenshots are being shown.
49+ i.e. during application window transitions */
50+ readonly property bool usingScreenshots: {
51+ if (newApplicationScreenshot.application != null && oldApplicationScreenshot.application != null) {
52+ return newApplicationScreenshot.ready && oldApplicationScreenshot.ready;
53+ } else {
54+ return newApplicationScreenshot.ready || oldApplicationScreenshot.ready;
55+ }
56+ }
57+
58+ property bool rightEdgeEnabled: true
59+ property bool switchingFromFullscreenToFullscreen: false
60+
61+ property alias rightEdgeDraggingAreaWidth: rightEdgeDraggingArea.width
62+
63+ // Y coordinate for non-fullscreen applications
64+ property int normalApplicationY: 0
65+
66+ function activateApplication(desktopFile, addDelay) {
67+ var application = applicationManager.getApplicationFromDesktopFile(desktopFile, stage.type);
68+ if (application != null && application == stage.focusedApplication) {
69+ stage.show();
70+ return;
71+ }
72+
73+ showStartingApplicationAnimation.prepare(application);
74+ if (!stage.fullyShown) {
75+ // if launching this app reveals the stage, make new application screenshot visible
76+ newApplicationScreenshot.visible = true;
77+ stage.show();
78+ } else {
79+ showStartingApplicationAnimation.start();
80+ }
81+
82+ if (addDelay) {
83+ stage.__startingApplicationDesktopFile = desktopFile;
84+ }
85+ }
86+
87+ Connections {
88+ target: applicationManager
89+ onFocusRequested: activateApplication(appId)
90+ }
91+
92+ /* Keep a reference to the focused application so that we can safely
93+ unfocus it when the stage is not fully shown and refocus it when the stage
94+ is fully shown again.
95+ */
96+ property var focusedApplicationWhenUsingScreenshots
97+ onShouldUseScreenshotsChanged: {
98+ if (showStartingApplicationAnimation.running || switchToApplicationAnimation.running) {
99+ return;
100+ }
101+
102+ if (shouldUseScreenshots) {
103+ stage.__focusApplicationUsingScreenshots(stage.focusedApplication);
104+ } else {
105+ if (stage.focusedApplicationWhenUsingScreenshots) {
106+ stage.__focusActualApplication(stage.focusedApplicationWhenUsingScreenshots);
107+ }
108+ }
109+ }
110+
111+
112+ property Item newApplicationScreenshot: ApplicationScreenshot {
113+ parent: stage
114+ width: stage.width
115+ height: stage.height - y
116+ }
117+ property Item oldApplicationScreenshot: ApplicationScreenshot {
118+ parent: stage
119+ width: stage.width
120+ height: stage.height - y
121+ }
122+
123+ function __getApplicationIndex(application) {
124+ if (!application)
125+ return -1
126+ for (var i = 0; i < stage.applications.count; i++ ) {
127+ if (stage.applications.get(i).desktopFile == application.desktopFile) {
128+ return i
129+ }
130+ }
131+ return -1
132+ }
133+
134+
135+ property string __startingApplicationDesktopFile
136+
137+ Timer {
138+ id: delayedHideScreenshots
139+ interval: 500 // on Galaxy Nexus, Telephony app is slowest application to draw a frame so needs this delay
140+ onTriggered: {
141+ __hideScreenshots();
142+ }
143+ }
144+
145+ function __hideScreenshots() {
146+ newApplicationScreenshot.clearApplication();
147+ oldApplicationScreenshot.clearApplication();
148+ newApplicationScreenshot.visible = false;
149+ oldApplicationScreenshot.visible = false;
150+ }
151+
152+ function __focusApplication(application) {
153+ if (!application) return
154+ if (shouldUseScreenshots) {
155+ stage.__focusApplicationUsingScreenshots(application);
156+ } else {
157+ stage.__focusActualApplication(application);
158+ }
159+ }
160+
161+
162+ function __focusActualApplication(application) {
163+ if (application == null) {
164+ return;
165+ }
166+
167+ if (stage.focusedApplication == application) {
168+ /* FIXME: this case is reached when showing the sidestage, we
169+ need to refocus the side stage app in order to show it.
170+ FIXME: this case is reached when doing a right edge swipe
171+ while in the dash to bring back the stage.
172+ FIXME: this case is reached when showStartingApplicationAnimation
173+ finishes after the newly started application has been focused
174+ automatically by the ApplicationManager.
175+ */
176+ if (stage.type == ApplicationInfo.SideStage) {
177+ applicationManager.focusApplication(application);
178+ }
179+ if (!delayedHideScreenshots.running) {
180+ stage.__hideScreenshots();
181+ }
182+ } else {
183+ /* FIXME: calling ApplicationManager::focusApplication does not focus
184+ the application immediately nor show the application's surface
185+ immediately. Delay hiding the screenshots until it has done so.
186+ */
187+ delayedHideScreenshots.stop();
188+ applicationManager.focusApplication(application);
189+ }
190+ stage.focusedApplicationWhenUsingScreenshots = null;
191+ }
192+
193+ function __focusApplicationUsingScreenshots(application) {
194+ delayedHideScreenshots.stop();
195+ if (application == null) {
196+ return;
197+ }
198+
199+ if (newApplicationScreenshot.application != null) {
200+ stage.focusedApplicationWhenUsingScreenshots = application;
201+ return;
202+ }
203+
204+ newApplicationScreenshot.setApplication(application);
205+ newApplicationScreenshot.scheduleUpdate();
206+ newApplicationScreenshot.opacity = 1.0;
207+ newApplicationScreenshot.x = 0.0;
208+ newApplicationScreenshot.y = __getApplicationY(application);
209+ newApplicationScreenshot.scale = 1.0;
210+ newApplicationScreenshot.visible = true;
211+ stage.focusedApplicationWhenUsingScreenshots = application;
212+ stage.switchingFromFullscreenToFullscreen = false;
213+ }
214+
215+ function __getApplicationY(application) {
216+ return Qt.binding( function(){
217+ return (application && application.fullscreen
218+ && application.stage !== ApplicationInfo.SideStage)
219+ ? 0 : normalApplicationY;
220+ } )
221+ }
222+
223+ /* FIXME: should hide the screenshots when the focused application's surface
224+ is visible. There is no API in QtUbuntu to support that yet.
225+ */
226+ Connections {
227+ target: stage
228+ onFocusedApplicationChanged: {
229+ if (stage.focusedApplication != null) {
230+ /* Move application to the beginning of the list of running applications */
231+ var index = stage.__getApplicationIndex(stage.focusedApplication);
232+ applicationManager.moveRunningApplicationStackPosition(index, 0, stage.type);
233+
234+ var startingApplication = applicationManager.getApplicationFromDesktopFile(
235+ stage.__startingApplicationDesktopFile, stage.type);
236+
237+ if (stage.focusedApplication == startingApplication) {
238+ stage.__startingApplicationDesktopFile = "";
239+
240+ /* Screenshots might still be in use at this point and their
241+ use can be stopped before delayedHideScreenshots is complete.
242+ Prepare for that case by setting appropriately
243+ stage.focusedApplicationWhenUsingScreenshots.
244+ */
245+ stage.focusedApplicationWhenUsingScreenshots = stage.focusedApplication;
246+
247+ /* FIXME: should hide the screenshots when the focused application's window
248+ is visible. There is no API in qtubuntu to support that yet. Therefore
249+ we delay their hiding to avoid a state where neither the screenshot nor
250+ the application's window is visible.
251+ */
252+ delayedHideScreenshots.start();
253+ } else {
254+ stage.focusedApplicationWhenUsingScreenshots = null;
255+ stage.__hideScreenshots();
256+ }
257+ }
258+ }
259+ }
260+
261+ Connections {
262+ target: stage.applications
263+ onCountChanged: { __discardObsoleteScreenshots(); }
264+ ignoreUnknownSignals: true
265+ }
266+ onFullyHiddenChanged: { __discardObsoleteScreenshots(); }
267+ function __discardObsoleteScreenshots() {
268+ if (stage.fullyHidden && stage.applications && stage.applications.count == 0) {
269+ stage.focusedApplicationWhenUsingScreenshots = undefined;
270+ stage.__hideScreenshots();
271+ }
272+ }
273+
274+
275+ SequentialAnimation {
276+ id: showStartingApplicationAnimation
277+
278+ function prepare(newApplication) {
279+ var oldApplication = stage.focusedApplication;
280+ newApplicationScreenshot.setApplication(newApplication);
281+ newApplicationScreenshot.updateFromCache();
282+ oldApplicationScreenshot.setApplication(oldApplication);
283+ oldApplicationScreenshot.scheduleUpdate();
284+ newApplicationScreenshot.withBackground = true; // FIXME: should be withBackground = newApplication.state == Application.Starting
285+ newApplicationScreenshot.y = __getApplicationY(newApplication);
286+ oldApplicationScreenshot.y = __getApplicationY(oldApplication);
287+ stage.focusedApplicationWhenUsingScreenshots = newApplication;
288+ stage.switchingFromFullscreenToFullscreen = false;
289+ }
290+
291+ PropertyAction {target: newApplicationScreenshot; property: "visible"; value: false}
292+ PropertyAction {target: oldApplicationScreenshot; property: "visible"; value: false}
293+ PropertyAction {target: newApplicationScreenshot; property: "z"; value: 0}
294+ PropertyAction {target: oldApplicationScreenshot; property: "z"; value: 1}
295+ PropertyAction {target: newApplicationScreenshot; property: "scale"; value: 0.8}
296+ PropertyAction {target: oldApplicationScreenshot; property: "scale"; value: 1.0}
297+ PropertyAction {target: newApplicationScreenshot; property: "opacity"; value: 0.0}
298+ PropertyAction {target: oldApplicationScreenshot; property: "opacity"; value: 1.0}
299+ PropertyAction {target: newApplicationScreenshot; property: "x"; value: 0.0}
300+ PropertyAction {target: oldApplicationScreenshot; property: "x"; value: 0.0}
301+
302+ ParallelAnimation {
303+ PropertyAction {target: newApplicationScreenshot; property: "visible"; value: true}
304+ NumberAnimation {
305+ target: newApplicationScreenshot
306+ property: "scale"
307+ duration: 500
308+ easing.type: Easing.OutQuad
309+ to: 1.0
310+ }
311+ NumberAnimation {
312+ target: newApplicationScreenshot
313+ property: "opacity"
314+ duration: 500
315+ easing.type: Easing.OutQuad
316+ to: 1.0
317+ }
318+
319+ PropertyAction {target: oldApplicationScreenshot; property: "visible"; value: true}
320+
321+ NumberAnimation {
322+ target: oldApplicationScreenshot
323+ property: "x"
324+ duration: 400
325+ easing.type: Easing.OutQuad
326+ to: stage.width
327+ }
328+ }
329+
330+ ScriptAction {
331+ script: {
332+ if (!stage.focusedApplicationWhenUsingScreenshots) {
333+ // FIXME: only here to support case where application does
334+ // not exist yet but is about to
335+ return;
336+ }
337+
338+ stage.__focusApplication(stage.focusedApplicationWhenUsingScreenshots);
339+ }
340+ }
341+ }
342+
343+
344+ SequentialAnimation {
345+ id: switchToApplicationAnimation
346+
347+ function prepare(newApplication) {
348+ var oldApplication = stage.focusedApplication;
349+ newApplicationScreenshot.setApplication(newApplication);
350+ newApplicationScreenshot.updateFromCache();
351+ oldApplicationScreenshot.setApplication(oldApplication);
352+ oldApplicationScreenshot.scheduleUpdate();
353+ newApplicationScreenshot.withBackground = false;
354+ newApplicationScreenshot.y = __getApplicationY(newApplication);
355+ oldApplicationScreenshot.y = __getApplicationY(oldApplication);
356+ stage.focusedApplicationWhenUsingScreenshots = newApplication;
357+ stage.switchingFromFullscreenToFullscreen = newApplication && newApplication.fullscreen;
358+ }
359+
360+ PropertyAction {target: newApplicationScreenshot; property: "visible"; value: false}
361+ PropertyAction {target: oldApplicationScreenshot; property: "visible"; value: false}
362+ PropertyAction {target: newApplicationScreenshot; property: "z"; value: 1}
363+ PropertyAction {target: oldApplicationScreenshot; property: "z"; value: 0}
364+ PropertyAction {target: newApplicationScreenshot; property: "scale"; value: 1.0}
365+ PropertyAction {target: oldApplicationScreenshot; property: "scale"; value: 1.0}
366+ PropertyAction {target: newApplicationScreenshot; property: "opacity"; value: 1.0}
367+ PropertyAction {target: oldApplicationScreenshot; property: "opacity"; value: 1.0}
368+ PropertyAction {target: newApplicationScreenshot; property: "x"; value: stage.width}
369+ PropertyAction {target: oldApplicationScreenshot; property: "x"; value: 0.0}
370+ PropertyAction {target: newApplicationScreenshot; property: "visible"; value: true}
371+ PropertyAction {target: oldApplicationScreenshot; property: "visible"; value: true}
372+
373+ ParallelAnimation {
374+ NumberAnimation {
375+ target: oldApplicationScreenshot
376+ property: "scale"
377+ duration: 500
378+ easing.type: Easing.OutQuad
379+ to: 0.8
380+ }
381+ NumberAnimation {
382+ target: oldApplicationScreenshot
383+ property: "opacity"
384+ duration: 500
385+ easing.type: Easing.OutQuad
386+ to: 0.0
387+ }
388+
389+ NumberAnimation {
390+ target: newApplicationScreenshot
391+ property: "x"
392+ duration: 500
393+ easing.type: Easing.OutQuad
394+ to: 0
395+ }
396+ }
397+
398+ ScriptAction {
399+ script: {
400+ // move previously focused application to the end of the list of running applications
401+ var oldApplication = oldApplicationScreenshot.application;
402+ if (oldApplication != null) {
403+ var oldApplicationIndex = stage.__getApplicationIndex(oldApplicationScreenshot.application);
404+ applicationManager.moveRunningApplicationStackPosition(
405+ oldApplicationIndex, stage.applications.count - 1, stage.type);
406+ }
407+
408+ stage.__focusApplication(stage.focusedApplicationWhenUsingScreenshots);
409+ }
410+ }
411+ }
412+
413+
414+ function __dragValueToProgress(dragValue, startValue, applicationsCount) {
415+ if (applicationsCount == 0) {
416+ return 0;
417+ } else if (applicationsCount == 1) {
418+ // prevent the current app from moving more than 1/4 of the screen
419+ var elasticValue = __elastic(dragValue, startValue/4);
420+ return elasticValue / startValue;
421+ } else {
422+ return dragValue / startValue;
423+ }
424+ }
425+
426+ function __elastic(x, limit) {
427+ return limit * ( 1 - Math.pow( ( limit - 1 ) / limit, x ) )
428+ }
429+
430+ property real __startValue: stage.width
431+
432+ AnimationControllerWithSignals {
433+ id: switchToApplicationAnimationController
434+
435+ onAnimationCompletedAtBeginning: {
436+ animation = null;
437+ stage.__focusApplication(oldApplicationScreenshot.application);
438+ }
439+ }
440+
441+ EdgeDragEvaluator {
442+ id: dragEvaluator
443+ trackedPosition: rightEdgeDraggingArea.touchX
444+ direction: rightEdgeDraggingArea.direction
445+ maxDragDistance: stage.width
446+ }
447+
448+ EdgeDragArea {
449+ id: rightEdgeDraggingArea
450+
451+ enabled: {
452+ if (status == DirectionalDragArea.WaitingForTouch) {
453+ return switchToApplicationAnimationController.completed
454+ && stage.applications.count > 0 && stage.rightEdgeEnabled
455+ && !delayedHideScreenshots.running
456+ } else {
457+ return true
458+ }
459+ }
460+ width: units.gu(2)
461+ anchors.top: parent.top
462+ anchors.bottom: parent.bottom
463+ anchors.right: parent.right
464+
465+ direction: Direction.Leftwards
466+
467+ onDistanceChanged: {
468+ if (status !== DirectionalDragArea.Recognized)
469+ return
470+
471+ var targetProgress = __dragValueToProgress(-distance, __startValue,
472+ stage.applications.count)
473+ var delta = targetProgress - switchToApplicationAnimationController.progress
474+
475+ // When the gesture finally gets recognized, the finger will likely be
476+ // reasonably far from the edge. If we made the progress immediately
477+ // follow the finger position it would be visually unpleasant as there
478+ // would be a jump to meet the finger's current position.
479+ //
480+ // The trick is not to go all the way (1.0) as it would cause the
481+ // aforementioned jump.
482+ switchToApplicationAnimationController.progress += 0.4 * delta
483+ }
484+
485+ property bool gotRejected: false
486+
487+ onStatusChanged: {
488+ if (status == DirectionalDragArea.Undecided) {
489+ gotRejected = false
490+ onUndecided();
491+ } else if (status == DirectionalDragArea.Rejected) {
492+ switchToApplicationAnimationController.completeToBeginningWithSignal();
493+ gotRejected = true;
494+ } else if (status == DirectionalDragArea.WaitingForTouch) {
495+ if (!gotRejected)
496+ onGestureEnded()
497+ }
498+ }
499+
500+ function onUndecided() {
501+ dragEvaluator.reset();
502+
503+ var nextApplication = null;
504+ if (stage.applications.count > 1) {
505+ nextApplication = stage.applications.get(1);
506+ }
507+ switchToApplicationAnimationController.progress = 0
508+ switchToApplicationAnimation.prepare(nextApplication);
509+ switchToApplicationAnimationController.animation = switchToApplicationAnimation;
510+
511+ }
512+
513+ function onGestureEnded() {
514+ if (stage.applications.count > 1 && dragEvaluator.shouldAutoComplete()) {
515+ switchToApplicationAnimationController.completeToEndWithSignal();
516+ } else {
517+ switchToApplicationAnimationController.completeToBeginningWithSignal();
518+ }
519+ }
520+ }
521+
522+
523+ // FIXME: very bad hack to detect when an application was closed or crashed
524+ property var __previouslyFocusedApplication
525+ Connections {
526+ target: stage
527+ onFocusedApplicationChanged: {
528+ if (stage.focusedApplication == null
529+ && __getApplicationIndex(stage.__previouslyFocusedApplication) == -1) {
530+ stage.__onFocusedApplicationClosed();
531+ }
532+ stage.__previouslyFocusedApplication = stage.focusedApplication;
533+ }
534+ }
535+
536+ function __onFocusedApplicationClosed() {
537+ if (!stage.shown) {
538+ return;
539+ }
540+
541+ if (stage.applications.count > 0) {
542+ // Do not change the focused application from within onFocusedApplicationChanged.
543+ // This causes binding loop warnings besides being a bad practice in general
544+ // (setting a property from within its "changed" signal handling)
545+ // Hence the timer.
546+ focusTopmostAppTimer.start();
547+ } else {
548+ stage.hide();
549+ }
550+ }
551+
552+ Timer {
553+ id: focusTopmostAppTimer
554+ interval: 1; repeat: false
555+ onTriggered: {
556+ if (stage.applications.count > 0) {
557+ stage.__focusApplication(stage.applications.get(0));
558+ }
559+ }
560+ }
561+
562+}
qml/Components/StandardAnimation.qml → Components/StandardAnimation.qmlrenamed+1−1
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18
18
19NumberAnimation {
19NumberAnimation {
20 duration: 200
20 duration: 200
qml/Wizard/StackButton.qml → Components/Tile.qmlrenamed+16−19
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2014-2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,29 +14,26 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19
19
20AbstractButton {
20AbstractButton {
21− id: stackButton
21+ property url source
22−
22+ property int fillMode: Image.PreserveAspectCrop
23+ property int horizontalAlignment: Text.AlignHCenter
23 property string text
24 property string text
25+ property int imageWidth
26+ property int imageHeight
27+ property int maximumLineCount: 1
24
28
25− property bool backArrow: false
29+ readonly property int center: (index % GridView.view.columns * width) + (width / 2)
26
30
27− width: label.width
31+ opacity: GridView.view.highlightIndex === -1 ? 1 :
28− height: units.gu(5)
32+ GridView.view.highlightIndex === index ? 0.6 : 0.2
29
33
30− Label {
31− id: label
32− anchors.verticalCenter: parent.verticalCenter
33− anchors.left: parent.left
34− anchors.right: parent.right
35− color: "#333333"
36− opacity: enabled ? 1.0 : 0.5
34+ Behavior on opacity {
37− fontSize: "medium"
35+ UbuntuNumberAnimation {}
38− font.weight: backArrow ? Font.Light : Font.DemiBold
39− text: stackButton.text
40− horizontalAlignment: backArrow ? Text.AlignLeft : Text.AlignRight
41 }
36 }
37+
38+ style: TileStyle {}
42}
39}
Components/TileStyle.qmlnew file+81
@@ -0,0 +1,81 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: tile
22+
23+ anchors.fill: parent
24+
25+ UbuntuShape {
26+ id: icon
27+ anchors {
28+ top: parent.top
29+ horizontalCenter: parent.horizontalCenter
30+ }
31+ radius: "medium"
32+ width: styledItem.imageWidth
33+ height: styledItem.imageHeight
34+ image: Image {
35+ id: image
36+ objectName: "image"
37+ sourceSize { width: icon.width; height: icon.height }
38+ asynchronous: true
39+ cache: false
40+ source: styledItem.source
41+ fillMode: styledItem.fillMode
42+ horizontalAlignment: Image.AlignHCenter
43+ verticalAlignment: Image.AlignVCenter
44+ }
45+ }
46+
47+ UbuntuShape {
48+ id: borderPressed
49+ objectName: "borderPressed"
50+
51+ anchors.fill: icon
52+ radius: "medium"
53+ borderSource: "radius_pressed.sci"
54+ opacity: styledItem.pressed ? 1.0 : 0.0
55+ Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
56+ }
57+
58+ Label {
59+ id: label
60+ objectName: "label"
61+ anchors {
62+ baseline: icon.bottom
63+ baselineOffset: units.gu(2)
64+ left: parent.left
65+ right: parent.right
66+ leftMargin: units.gu(1)
67+ rightMargin: units.gu(1)
68+ }
69+
70+ color: Theme.palette.selected.backgroundText
71+ opacity: 0.9
72+ style: Text.Raised
73+ styleColor: "black"
74+ fontSize: "small"
75+ elide: Text.ElideMiddle
76+ horizontalAlignment: styledItem.horizontalAlignment
77+ text: styledItem.text
78+ wrapMode: Text.Wrap
79+ maximumLineCount: styledItem.maximumLineCount
80+ }
81+}
Components/Time.jsnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+.pragma library
18+
19+var factors = [
20+ [ 1000, "a second ago", "in a second", "%1 seconds ago", "in %1 seconds" ],
21+ [ 60, "a minute ago", "in a minute", "%1 minutes ago", "in %1 minutes" ],
22+ [ 60, "an hour ago", "in an hour", "%1 hours ago", "in %1 hours" ],
23+ [ 24, "yesterday", "tomorrow", "%1 days ago", "in %1 days" ],
24+ [ 7, "a week ago", "in a week", "about %1 weeks ago", "in about %1 weeks" ],
25+ [ 4.35, "a month ago", "in a month", "%1 months ago", "in %1 months" ], // == 365.25 days / 12 months / 7 days
26+ [ 12, "a year ago", "in a year", "%1 years ago", "in %1 years" ]
27+]
28+
29+function readableFromNow(date, now) {
30+ var then = new Date(date);
31+ if (isNaN(then)) return "";
32+ if (now === undefined) {
33+ now = new Date();
34+ } else if (isNaN(now)) throw "now is NaN";
35+ var diff = Math.abs(now - then);
36+ if (diff < 1000) return "just now";
37+
38+ var future = now < then;
39+ var humanDiff;
40+ for (var k in factors) {
41+ diff /= factors[k][0];
42+ if (Math.floor(diff) == 1) {
43+ humanDiff = factors[k][future ? 2 : 1];
44+ } else if (Math.floor(diff) > 1) {
45+ humanDiff = factors[k][future ? 4 : 3].arg(Math.round(diff));
46+ } else break;
47+ }
48+ return humanDiff;
49+}
Components/UbuntuShapeForItem.qmlnew file+46
@@ -0,0 +1,46 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+/* FIXME: This component is duplicating the UbuntuShape from the SDK, but shapes more
21+ * general (Item-based) components. This ability should be incorporated into the SDK's
22+ * UbuntuShape so this file can be removed.
23+ * Bug: https://bugs.launchpad.net/tavastia/+bug/1089595
24+ */
25+
26+Item {
27+ id: root
28+
29+ property alias radius: shape.radius
30+ property alias image: source.sourceItem
31+
32+ ShaderEffectSource {
33+ id: source
34+ anchors.centerIn: parent // Placed under shape, so it's hidden
35+ width: 1
36+ height: 1
37+ hideSource: true
38+ }
39+
40+ Shape {
41+ id: shape
42+ image: source
43+
44+ anchors.fill: parent
45+ }
46+}
qml/Components/ItemSnapshot.qml → Components/VolumeControl.qmlrenamed+17−19
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015-2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,32 +14,30 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18+import QMenuModel 0.1
18
19
19Item {
20Item {
20 id: root
21 id: root
22+ objectName: "volumeControl"
23+ visible: false
21
24
22− property Item target
25+ QDBusActionGroup {
26+ id: actionGroup
27+ busType: 1
28+ busName: "com.canonical.indicator.sound"
29+ objectPath: "/com/canonical/indicator/sound"
23
30
24− property bool ready: image.status === Image.Ready
31+ property variant actionObject: action("volume")
25−
26− function take() {
27− if (!target) {
28− console.warn("ItemSnapshot.take(): no target set");
29− return;
30− }
31−
32− target.grabToImage(function(result) {
33− image.source = result.url;
34− });
35 }
32 }
36
33
37− // Unload the image to free up memory
38− function discard() {
34+ function volumeUp() {
39− image.source = "";
35+ actionGroup.actionObject.activate(1);
40 }
36 }
41
37
42− Image {
38+ function volumeDown() {
43− id: image
39+ actionGroup.actionObject.activate(-1);
44 }
40 }
41+
42+ Component.onCompleted: actionGroup.start()
45}
43}
qml/Components/WrongPasswordAnimation.qml → Components/WrongPasswordAnimation.qmlrenamed+1−1
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18
18
19SequentialAnimation {
19SequentialAnimation {
20 id: root
20 id: root
qml/Components/carousel.js → Components/carousel.jsrenamed

The content is the same.

Components/graphics/PageHeaderBaseDivider@18.pngnew file

Binary file not shown.

Components/graphics/PageHeaderBaseDivider@18.scinew file+5
@@ -0,0 +1,5 @@
1+border.top: 4
2+border.bottom: 4
3+border.left: 0
4+border.right: 0
5+source: PageHeaderBaseDivider@18.png
Components/graphics/close@20.pngnew file

Binary file not shown.

Components/graphics/icon_star_off@20.pngnew file

Binary file not shown.

Components/graphics/icon_star_on@20.pngnew file

Binary file not shown.

Components/graphics/non-selected@18.pngnew file

Binary file not shown.

qml/Components/graphics/non-selected@18.sci → Components/graphics/non-selected@18.scirenamed

The content is the same.

Dash/Apps/AppInfo.qmlnew file+89
@@ -0,0 +1,89 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+
21+Row {
22+ id: root
23+ property alias icon: image.source
24+ property alias appName: appNameLabel.text
25+ property alias rating: ratingStars.rating
26+ property int rated: 0
27+ property int reviews: 0
28+
29+ spacing: units.gu(2)
30+
31+ UbuntuShape {
32+ id: imageShape
33+ width: units.gu(6)
34+ height: units.gu(6)
35+ image: Image {
36+ id: image
37+ sourceSize { width: imageShape.width; height: imageShape.height }
38+ asynchronous: true
39+ fillMode: Image.PreserveAspectFit
40+ }
41+ }
42+
43+ Column {
44+ spacing: units.gu(1)
45+
46+ Label {
47+ id: appNameLabel
48+ fontSize: "large"
49+ color: "white"
50+ style: Text.Raised
51+ styleColor: "black"
52+ opacity: .9
53+ }
54+
55+ Row {
56+ visible: root.rating >= 0
57+ spacing: units.gu(1)
58+
59+ RatingStars {
60+ id: ratingStars
61+ maximumRating: 10
62+ }
63+
64+ Label {
65+ id: ratedLabel
66+ objectName: "ratedLabel"
67+ fontSize: "medium"
68+ color: "white"
69+ style: Text.Raised
70+ styleColor: "black"
71+ opacity: .6
72+ //TRANSLATORS: Number of persons who rated this app
73+ text: i18n.tr("(%1)").arg(root.rated)
74+ }
75+
76+ Label {
77+ id: reviewsLabel
78+ objectName: "reviewsLabel"
79+ fontSize: "medium"
80+ color: "white"
81+ style: Text.Raised
82+ styleColor: "black"
83+ opacity: .6
84+ //TRANSLATORS: Number of persons who wrote reviews for this app
85+ text: i18n.tr("%1 review", "%1 reviews", root.reviews).arg(root.reviews)
86+ }
87+ }
88+ }
89+}
Dash/Apps/AppPreview.qmlnew file+166
@@ -0,0 +1,166 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItems
20+import ".."
21+import "../Generic"
22+import "../Previews"
23+import "../../Components"
24+
25+GenericPreview {
26+ id: root
27+
28+ signal sendUserReview(string review)
29+
30+ previewImages: previewImagesComponent
31+ description: descriptionComponent
32+ header: headerComponent
33+
34+ // TODO: Ratings are not yet complete... enable this once they work
35+ //ratings: ratingsComponent
36+
37+ Component {
38+ id: previewImagesComponent
39+ ListView {
40+ id: previewImageListView
41+ spacing: units.gu(1)
42+ orientation: ListView.Horizontal
43+ height: units.gu(22)
44+ model: previewData.infoMap["more-screenshots"] != null ? previewData.infoMap["more-screenshots"].value : [previewData.image]
45+ cacheBuffer: width * 3
46+
47+ // FIXME: Because of ListViews inside ListViews inside Flickables inside ListViews (and some more)
48+ // we finally reached the point where this ListView doesn't correctly get swipe input any more but
49+ // instead the parent ListView is the one that is swiped. This MouseArea sort of creates a blocking
50+ // layer to make sure this ListView can be swiped, regardless of what's behind it.
51+ MouseArea {
52+ anchors.fill: parent
53+ enabled: parent.contentWidth > parent.width
54+ }
55+
56+ LazyImage {
57+ objectName: "placeholderScreenshot"
58+ anchors {
59+ top: parent.top
60+ bottom: parent.bottom
61+ }
62+ scaleTo: "height"
63+ source: "broken_image"
64+ initialWidth: units.gu(13)
65+ visible: previewImageListView.count == 0
66+ }
67+
68+ delegate: LazyImage {
69+ id: shape
70+ anchors {
71+ top: parent.top
72+ bottom: parent.bottom
73+ }
74+ source: modelData ? modelData : ""
75+ scaleTo: "height"
76+ initialWidth: units.gu(13)
77+ }
78+ }
79+ }
80+
81+ Component {
82+ id: headerComponent
83+ Header {
84+ objectName: "previewHeader"
85+ title: previewData.title
86+ icon: previewData.appIcon
87+ subtitle: root.previewData.infoMap["publisher"] ? root.previewData.infoMap["publisher"].value : ""
88+ rating: Math.round(root.previewData.rating * 10)
89+ reviews: root.previewData.numRatings
90+ rated: root.previewData.infoMap["rated"] ? root.previewData.infoMap["rated"].value : 0
91+ }
92+ }
93+
94+ Component {
95+ id: descriptionComponent
96+ Column {
97+ spacing: units.gu(1)
98+
99+ Label {
100+ anchors { left: parent.left; right: parent.right }
101+ text: root.previewData.description
102+ fontSize: "medium"
103+ color: Theme.palette.selected.backgroundText
104+ opacity: .6
105+ wrapMode: Text.WordWrap
106+ style: Text.Raised
107+ styleColor: "black"
108+ }
109+ }
110+ }
111+
112+ Component {
113+ id: ratingsComponent
114+ Column {
115+ id: columnReviewRating
116+ objectName: "columnReviewRating"
117+ visible: root.previewData.rating >= 0
118+
119+ spacing: units.gu(1)
120+ height: childrenRect.height
121+
122+ ListItems.ThinDivider { }
123+
124+ Item {
125+ anchors { left: parent.left; right: parent.right }
126+ height: rateLabel.height
127+
128+ Label {
129+ id: rateLabel
130+ fontSize: "medium"
131+ color: "white"
132+ style: Text.Raised
133+ styleColor: "black"
134+ opacity: .9
135+ text: i18n.tr("Rate this")
136+
137+ anchors.left: parent.left
138+ anchors.verticalCenter: parent.verticalCenter
139+ }
140+
141+ // FIXME these need to be made interactive and connected to the scope
142+ RatingStars {
143+ anchors.right: parent.right
144+ anchors.verticalCenter: parent.verticalCenter
145+ }
146+ }
147+
148+ ListItems.ThinDivider { }
149+
150+ Reviews {
151+ id: appReviews
152+ objectName: "appReviews"
153+
154+ anchors { left: parent.left; right: parent.right }
155+
156+ model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
157+
158+ onSendReview: root.sendUserReview(review);
159+
160+ onEditing: {
161+ root.ensureVisible(appReviews.textArea);
162+ }
163+ }
164+ }
165+ }
166+}
Dash/Apps/ApplicationsFilterGrid.qmlnew file+64
@@ -0,0 +1,64 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+import "../../Applications"
20+
21+FilterGrid {
22+ id: filtergrid
23+
24+ filter: false
25+ minimumHorizontalSpacing: units.gu(0.5)
26+ maximumNumberOfColumns: 6
27+ delegateWidth: units.gu(11)
28+ delegateHeight: units.gu(9.5)
29+ verticalSpacing: units.gu(2)
30+
31+ signal clicked(int index, var model, real itemY)
32+ signal pressAndHold(int index, var model, real itemY)
33+
34+ delegate: Tile {
35+ id: tile
36+ objectName: "delegate" + index
37+ Application {
38+ id: application
39+ desktopFile: model.dndUri ? stripProtocol(model.dndUri) : model.desktopFile // FIXME: this is temporary
40+
41+ function stripProtocol(uri) {
42+ var chunks = uri.split('file://')
43+ return chunks[chunks.length-1]
44+ }
45+ }
46+
47+ property string icon: model.icon ? model.icon : "../../graphics/applicationIcons/" + application.icon + ".png" // FIXME: this is temporary
48+
49+ width: filtergrid.cellWidth
50+ height: filtergrid.cellHeight
51+ text: model.title ? model.title : application.name // FIXME: this is temporary
52+ imageWidth: units.gu(8)
53+ imageHeight: units.gu(7.5)
54+ source: icon
55+
56+ onClicked: {
57+ filtergrid.clicked(index, filtergrid.model, tile.y)
58+ }
59+
60+ onPressAndHold: {
61+ filtergrid.pressAndHold(index, filtergrid.model, tile.y)
62+ }
63+ }
64+}
Dash/Apps/CloseIcon.qmlnew file+62
@@ -0,0 +1,62 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+Item {
20+ id: root
21+
22+ Image {
23+ id: closeIcon
24+ anchors.centerIn: parent
25+ source: "graphics/close_btn.png"
26+
27+ state: (root.enabled) ? "shown" : "hidden"
28+
29+ states: [
30+ State {
31+ name: "shown"
32+ PropertyChanges {
33+ target: closeIcon
34+ height: root.height
35+ width: root.width
36+ }
37+ },
38+ State {
39+ name: "hidden"
40+ PropertyChanges {
41+ target: closeIcon
42+ height: 0
43+ width: 0
44+ }
45+ }
46+
47+ ]
48+ transitions: [
49+ Transition {
50+ to: "shown"
51+ NumberAnimation {
52+ properties: "width, height"; duration: 300
53+ easing { type: Easing.OutBack; overshoot: 5 }
54+ }
55+ },
56+ Transition {
57+ to: "hidden"
58+ NumberAnimation { properties: "width, height"; duration: 250; }
59+ }
60+ ]
61+ }
62+}
Dash/Apps/DashPluginFilterGrid.qmlnew file+47
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+import "../Generic"
21+
22+GenericFilterGrid {
23+ id: filtergrid
24+
25+ delegate: Tile {
26+ id: tile
27+ objectName: "delegate" + index
28+ width: filtergrid.cellWidth
29+ height: filtergrid.cellHeight
30+ text: model.title
31+ imageWidth: filtergrid.iconWidth
32+ imageHeight: filtergrid.iconHeight
33+ source: model.icon
34+
35+ style: FlatTileStyle {
36+ disabled: model.rendererHints['scope_disabled'] === 1;
37+ }
38+
39+ onClicked: {
40+ filtergrid.clicked(index, filtergrid.model, tile.y)
41+ }
42+
43+ onPressAndHold: {
44+ filtergrid.pressAndHold(index, filtergrid.model, tile.y)
45+ }
46+ }
47+}
Dash/Apps/FrequentlyUsedAppsModel.qmlnew file+110
@@ -0,0 +1,110 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+ListModel {
20+ ListElement {
21+ uri: "application://dialer-app.desktop"
22+ icon: "../../graphics/applicationIcons/phone-app.png"
23+ category: 0
24+ mimetype: "application/x-desktop"
25+ title: "Dialer"
26+ comment: ""
27+ dndUri: "file:///usr/share/applications/dialer-app.desktop"
28+ metadata: "subscope:applications.scope/applications-non-click.scope"
29+ }
30+ ListElement {
31+ uri: "application://messaging-app.desktop"
32+ icon: "../../graphics/applicationIcons/messages-app.png"
33+ category: 0
34+ mimetype: "application/x-desktop"
35+ title: "Messaging"
36+ comment: ""
37+ dndUri: "file:///usr/share/applications/messaging-app.desktop"
38+ metadata: "subscope:applications.scope/applications-non-click.scope"
39+ }
40+ ListElement {
41+ uri: "application://address-book-app.desktop"
42+ icon: "../../graphics/applicationIcons/contacts-app.png"
43+ category: 0
44+ mimetype: "application/x-desktop"
45+ title: "Contacts"
46+ comment: ""
47+ dndUri: "file:///usr/share/applications/address-book-app.desktop"
48+ metadata: "subscope:applications.scope/applications-non-click.scope"
49+ }
50+ ListElement {
51+ uri: "application://camera-app.desktop"
52+ icon: "../../graphics/applicationIcons/camera.png"
53+ category: 0
54+ mimetype: "application/x-desktop"
55+ title: "Camera"
56+ comment: ""
57+ dndUri: "file:///usr/share/applications/camera-app.desktop"
58+ metadata: "subscope:applications.scope/applications-non-click.scope"
59+ }
60+ ListElement {
61+ uri: "application://gallery-app.desktop"
62+ icon: "../../graphics/applicationIcons/gallery.png"
63+ category: 0
64+ mimetype: "application/x-desktop"
65+ title: "Gallery"
66+ comment: ""
67+ dndUri: "file:///usr/share/applications/gallery.desktop"
68+ metadata: "subscope:applications.scope/applications-non-click.scope"
69+ }
70+ ListElement {
71+ uri: "appid://com.ubuntu.developer.webapps.webapp-facebook/webapp-facebook/current-user-version"
72+ icon: "../../graphics/applicationIcons/facebook.png"
73+ category: 0
74+ mimetype: "application/x-desktop"
75+ title: "Facebook"
76+ comment: ""
77+ dndUri: "appid://com.ubuntu.developer.webapps.webapp-facebook/webapp-facebook/current-user-version"
78+ metadata: "subscope:applications.scope/applications-click.scope?app_id=com.ubuntu.developer.webapps.webapp-facebook"
79+ }
80+ ListElement {
81+ uri: "application://webbrowser-app.desktop"
82+ icon: "../../graphics/applicationIcons/browser.png"
83+ category: 0
84+ mimetype: "application/x-desktop"
85+ title: "Browser"
86+ comment: ""
87+ dndUri: "file:///usr/share/applications/webbrowser-app.desktop"
88+ metadata: "subscope:applications.scope/applications-non-click.scope"
89+ }
90+ ListElement {
91+ uri: "appid://com.ubuntu.developer.webapps.webapp-gmail/webapp-gmail/current-user-version"
92+ icon: "../../graphics/applicationIcons/gmail.png"
93+ category: 0
94+ mimetype: "application/x-desktop"
95+ title: "GMail"
96+ comment: ""
97+ dndUri: "appid://com.ubuntu.developer.webapps.webapp-gmail/webapp-gmail/current-user-version"
98+ metadata: "subscope:applications.scope/applications-click.scope?app_id=com.ubuntu.developer.webapps.webapp-gmail"
99+ }
100+ ListElement {
101+ uri: "application://ubuntu-system-settings.desktop"
102+ icon: "../../graphics/applicationIcons/system-settings.png"
103+ category: 0
104+ mimetype: "application/x-desktop"
105+ title: "System Settings"
106+ comment: ""
107+ dndUri: "file:///usr/share/applications/ubuntu-system-settings.desktop"
108+ metadata: "subscope:applications.scope/applications-non-click.scope"
109+ }
110+}
Dash/Apps/RunningApplicationTile.qmlnew file+141
@@ -0,0 +1,141 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity.Application 0.1
20+import "../../Components/"
21+import "../../Components/ListItems"
22+
23+AbstractButton {
24+ id: root
25+ property var application
26+ property bool __sideStageEnabled: shell.applicationManager.sideStageEnabled
27+
28+ signal requestedApplicationActivation(var application)
29+ signal requestedApplicationTermination(var application)
30+ signal requestedActivationMode()
31+ signal requestedTerminationMode()
32+
33+ // Was: childrenRect.height
34+ // To avoid "binding loop" warning
35+ height: shapedApplicationImage.height + labelContainer.height
36+
37+ width: shapedApplicationImage.width
38+
39+ property bool terminationModeEnabled: false
40+
41+ onClicked: {
42+ if (!terminationModeEnabled)
43+ requestedApplicationActivation(application)
44+ }
45+
46+ onPressAndHold: {
47+ if (terminationModeEnabled) {
48+ requestedActivationMode()
49+ } else {
50+ requestedTerminationMode()
51+ }
52+ }
53+
54+ function updateScreenshotFromCache() {
55+ applicationImage.updateFromCache();
56+ }
57+
58+ // FIXME: should use UbuntuShape from SDK
59+ UbuntuShapeForItem {
60+ id: shapedApplicationImage
61+ anchors {
62+ top: parent.top
63+ horizontalCenter: parent.horizontalCenter
64+ }
65+
66+ // FIXME: width and height should be defined according to the
67+ // application window's aspect ratio.
68+ width: (application.stage === ApplicationInfo.MainStage && __sideStageEnabled) ?
69+ units.gu(22) : units.gu(11)
70+ height: (__sideStageEnabled) ? units.gu(22) : units.gu(19)
71+ radius: "medium"
72+ image: applicationImage
73+ }
74+
75+ ApplicationImage {
76+ id: applicationImage
77+ source: ApplicationManager.findApplication((application) ? application.appId : "")
78+ width: shapedApplicationImage.width
79+ height: shapedApplicationImage.height
80+ }
81+
82+ UbuntuShape {
83+ id: borderPressed
84+
85+ anchors.fill: shapedApplicationImage
86+ radius: "medium"
87+ borderSource: "radius_pressed.sci"
88+ opacity: root.pressed ? 1.0 : 0.0
89+ Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
90+ }
91+
92+ // FIXME: label code duplicated with Tile
93+ Item {
94+ id: labelContainer
95+ anchors {
96+ left: parent.left
97+ right: parent.right
98+ top: shapedApplicationImage.bottom
99+ }
100+ height: units.gu(2)
101+
102+ Label {
103+ id: label
104+ anchors {
105+ baseline: parent.bottom
106+ left: parent.left
107+ right: parent.right
108+ leftMargin: units.gu(1)
109+ rightMargin: units.gu(1)
110+ }
111+ text: (application) ? application.name : ""
112+
113+ color: Theme.palette.selected.backgroundText
114+ opacity: 0.9
115+ style: Text.Raised
116+ styleColor: "black"
117+ fontSize: "small"
118+ elide: Text.ElideMiddle
119+ horizontalAlignment: Text.AlignHCenter
120+ }
121+ }
122+
123+ CloseIcon {
124+ objectName: "closeIcon " + model.name
125+ anchors {
126+ left: shapedApplicationImage.left
127+ leftMargin: -units.gu(1)
128+ top: parent.top
129+ topMargin: -units.gu(1)
130+ }
131+ height: units.gu(6)
132+ width: units.gu(6)
133+ id: closeIcon
134+ enabled: root.terminationModeEnabled
135+
136+ MouseArea {
137+ anchors { fill: parent; margins: -units.gu(1) }
138+ onClicked: requestedApplicationTermination(application)
139+ }
140+ }
141+}
Dash/Apps/RunningApplicationsGrid.qmlnew file+103
@@ -0,0 +1,103 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+
20+ResponsiveFlowView {
21+ id: root
22+ clip: true
23+
24+ signal updateScreenshots
25+ property alias enableHeightBehavior: heightBehaviour.enabled
26+ property bool enableHeightBehaviorOnNextCreation: firstModel.count + secondModel.count == 0
27+
28+ Connections {
29+ target: shell
30+ onDashShownChanged: if (shell.dashShown && shell.stageScreenshotsReady) updateScreenshots();
31+ onStageScreenshotsReadyChanged: if (shell.dashShown && shell.stageScreenshotsReady) updateScreenshots();
32+ }
33+
34+ Behavior on height {
35+ id: heightBehaviour
36+ enabled: false
37+ NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
38+ }
39+
40+ Connections {
41+ target: root.firstModel
42+ onCountChanged: {
43+ heightBehaviour.enabled = true;
44+ }
45+ }
46+ Connections {
47+ target: root.secondModel
48+ onCountChanged: {
49+ heightBehaviour.enabled = true;
50+ }
51+ }
52+
53+ property bool canEnableTerminationMode: true
54+
55+ onCanEnableTerminationModeChanged: {
56+ if (!canEnableTerminationMode)
57+ terminationModeEnabled = false
58+ }
59+
60+ // when false, it means it's on activation mode
61+ property bool terminationModeEnabled: false
62+
63+ maximumNumberOfColumns: 10
64+ minimumHorizontalSpacing: units.gu(2)
65+ referenceDelegateWidth: units.gu(11)
66+ verticalSpacing: units.gu(2)
67+
68+ delegate: Item {
69+ width: runningAppTile.width + root.horizontalSpacing
70+ height: runningAppTile.height + root.verticalSpacing
71+
72+ RunningApplicationTile {
73+ id: runningAppTile
74+ objectName: "runningAppTile " + model.name
75+ anchors {
76+ top: parent.top
77+ horizontalCenter: parent.horizontalCenter
78+ }
79+ application: model
80+ onRequestedActivationMode: { root.terminationModeEnabled = false }
81+ onRequestedTerminationMode: {
82+ if (canEnableTerminationMode)
83+ root.terminationModeEnabled = true
84+ }
85+ onRequestedApplicationTermination: {
86+ shell.applicationManager.stopApplication(model.appId)
87+ }
88+ onRequestedApplicationActivation: {
89+ shell.activateApplication(model.appId)
90+ }
91+
92+ terminationModeEnabled: root.terminationModeEnabled
93+
94+ Component.onCompleted: {
95+ root.updateScreenshots.connect(updateScreenshotFromCache);
96+ }
97+ }
98+ }
99+
100+ move: Transition {
101+ NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutCubic }
102+ }
103+}
Dash/Apps/graphics/close_btn@9.pngnew file

Binary file not shown.

Dash/Dash.qmlnew file+93
@@ -0,0 +1,93 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity 0.1
20+import Utils 0.1
21+import "../Components"
22+
23+Showable {
24+ id: dash
25+ objectName: "dash"
26+
27+ visible: shown
28+
29+ property alias contentProgress: dashContent.contentProgress
30+ property string showScopeOnLoaded: "home.scope"
31+ property real contentScale: 1.0
32+
33+ function setCurrentScope(scopeId, animate, reset) {
34+ var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
35+
36+ if (scopeIndex == -1) {
37+ console.warn("No match for scope with id: %1".arg(scopeId))
38+ return
39+ }
40+
41+ if (scopeIndex == dashContent.currentIndex && !reset) {
42+ // the scope is already the current one
43+ return
44+ }
45+
46+ dashContent.setCurrentScopeAtIndex(scopeIndex, animate, reset)
47+ }
48+
49+ SortFilterProxyModel {
50+ id: filteredScopes
51+ model: Scopes {
52+ id: scopes
53+ }
54+ dynamicSortFilter: true
55+
56+ filterRole: Scopes.RoleVisible
57+ filterRegExp: RegExp("^true$")
58+ }
59+
60+ DashContent {
61+ id: dashContent
62+ objectName: "dashContent"
63+ anchors.fill: parent
64+ model: filteredScopes
65+ scopes: scopes
66+ onMovementStarted: dashbar.startNavigation()
67+ onMovementEnded: dashbar.stopNavigation()
68+ onContentFlickStarted: dashbar.finishNavigation()
69+ onContentEndReached: dashbar.finishNavigation()
70+ onPreviewShown: dashbar.finishNavigation()
71+ onScopeLoaded: {
72+ if (scopeId == dash.showScopeOnLoaded) {
73+ dash.setCurrentScope(scopeId, false, false)
74+ dash.showScopeOnLoaded = ""
75+ }
76+ }
77+ scale: dash.contentScale
78+ clip: scale != 1.0
79+ }
80+
81+ DashBar {
82+ id: dashbar
83+ objectName: "dashbar"
84+ anchors.bottom: parent.bottom
85+ anchors.left: parent.left
86+ anchors.right: parent.right
87+ model: filteredScopes
88+ currentIndex: dashContent.currentIndex
89+ onItemSelected: dashContent.setCurrentScopeAtIndex(index, true, false)
90+ opacity: dash.contentScale == 1.0 ? 1.0 : 0.0
91+ Behavior on opacity { NumberAnimation { easing.type: Easing.OutQuad; duration: 150 } }
92+ }
93+}
Dash/DashApps.qmlnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Utils 0.1
20+import "../Components"
21+import "../Components/ListItems"
22+import "../Applications"
23+import "Apps"
24+
25+GenericScopeView {
26+ id: scopeView
27+ objectName: "DashApps"
28+
29+ // FIXME: a way to aggregate these models would be ideal
30+ property var mainStageApplicationsModel: shell.applicationManager.mainStageApplications
31+ property var sideStageApplicationModel: shell.applicationManager.sideStageApplications
32+
33+ ListModel {
34+ id: dummyVisibilityModifier
35+
36+ ListElement { name: "running-apps" }
37+ }
38+
39+ SortFilterProxyModel {
40+ id: runningApplicationsModel
41+
42+ property var firstModel: mainStageApplicationsModel
43+ property var secondModel: sideStageApplicationModel
44+ property bool canEnableTerminationMode: scopeView.isCurrent
45+
46+ model: dummyVisibilityModifier
47+ filterRole: 0
48+ filterRegExp: invertMatch ? ((mainStageApplicationsModel.count === 0 &&
49+ sideStageApplicationModel.count === 0) ? RegExp("running-apps") : RegExp("")) : RegExp("disabled")
50+ invertMatch: scopeView.scope.searchQuery.length == 0
51+ }
52+
53+ onScopeChanged: {
54+ scopeView.scope.categories.overrideResults("recent", runningApplicationsModel);
55+ enableHeightBehaviorOnNextCreation = (mainStageApplicationsModel.count + sideStageApplicationModel.count == 0)
56+ }
57+}
Dash/DashBar.qmlnew file+128
@@ -0,0 +1,128 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity 0.1
20+
21+Item {
22+ id: dashBar
23+
24+ property var model
25+ property alias currentIndex: row.currentIndex
26+
27+ property int lineHeight: units.dp(2)
28+ property int itemSize: units.gu(7)
29+ property int iconSize: units.gu(3.5)
30+
31+ signal itemSelected(int index)
32+
33+ width: units.gu(40)
34+ height: units.gu(6)
35+
36+ function startNavigation() {
37+ timeout.stop()
38+ panel.open()
39+ }
40+
41+ function stopNavigation() {
42+ timeout.restart()
43+ }
44+
45+ function finishNavigation() {
46+ panel.close()
47+ }
48+
49+ Timer {
50+ id: timeout
51+ interval: 1500
52+ running: false
53+ repeat: false
54+ onTriggered: finishNavigation()
55+ }
56+
57+ Panel {
58+ id: panel
59+ objectName: "panel"
60+ anchors.fill: parent
61+
62+ locked: true // TODO: remove this when lp bug #1179569 will be fixed
63+
64+ Rectangle {
65+ color: "black"
66+ anchors.fill: parent
67+
68+ ListView {
69+ id: row
70+ objectName: "row"
71+ model: dashBar.model
72+ orientation: ListView.Horizontal
73+ width: Math.min(Math.max(dashBar.width/2, units.gu(40)), count * itemSize)
74+ height: parent.height
75+ anchors.horizontalCenter: parent.horizontalCenter
76+ onMovingChanged: if (moving) { timeout.stop() } else { timeout.restart() }
77+ interactive: visibleArea.widthRatio < 1 && panel.opened
78+ highlightFollowsCurrentItem: false
79+
80+ onCurrentItemChanged: {
81+ highlightLine.width = currentItem.width
82+ highlightLine.x = x + currentItem.x
83+ }
84+
85+ delegate:
86+ // FIXME: Use Panel's integrated trigger() once that works again.
87+ MouseArea {
88+ width: itemSize
89+ height: dashBar.height
90+ anchors.top: parent.top
91+
92+ onClicked: {
93+ dashBar.itemSelected(index)
94+ timeout.restart()
95+ }
96+
97+ Image {
98+ anchors.centerIn: parent
99+ source: scope.iconHint
100+ sourceSize { width: iconSize; height: iconSize }
101+ // opacity: index == currentIndex ? 1 : 1 // same opacity for now
102+ }
103+ }
104+ }
105+ }
106+ }
107+
108+ Rectangle {
109+ anchors {
110+ left: parent.left
111+ right: parent.right
112+ bottom: parent.bottom
113+ }
114+ height: dashBar.lineHeight
115+ color: "black"
116+
117+ Rectangle {
118+ id: highlightLine
119+ color: Theme.palette.selected.foreground
120+ height: parent.height
121+ anchors.bottom: parent.bottom
122+ z: 1
123+
124+ Behavior on x {NumberAnimation { duration: 150; easing.type: Easing.OutCubic}}
125+ Behavior on width {NumberAnimation { duration: 150; easing.type: Easing.OutCubic}}
126+ }
127+ }
128+}
Dash/DashContent.qmlnew file+149
@@ -0,0 +1,149 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity 0.1
20+
21+Item {
22+ id: dashContent
23+
24+ property var model: null
25+ property var scopes: null
26+ property real contentProgress: Math.max(0, Math.min(dashContentList.contentX / (dashContentList.contentWidth - dashContentList.width), units.dp(1)))
27+ property alias currentIndex: dashContentList.currentIndex
28+
29+ property ScopeDelegateMapper scopeMapper : ScopeDelegateMapper {}
30+
31+ signal movementStarted()
32+ signal movementEnded()
33+ signal contentFlickStarted()
34+ signal contentEndReached()
35+ signal previewShown()
36+ signal scopeLoaded(string scopeId)
37+ signal positionedAtBeginning()
38+
39+ // If we set the current scope index before the scopes have been added,
40+ // then we need to wait until the loaded signals gets emitted from the scopes
41+ property var set_current_index: undefined
42+ Connections {
43+ target: scopes
44+ onLoadedChanged: {
45+ if (scopes.loaded && set_current_index != undefined) {
46+ setCurrentScopeAtIndex(set_current_index[0], set_current_index[1], set_current_index[2]);
47+ set_current_index = undefined;
48+ }
49+ }
50+ }
51+
52+ function setCurrentScopeAtIndex(index, animate, reset) {
53+ var storedMoveDuration = dashContentList.highlightMoveDuration
54+ var storedMoveSpeed = dashContentList.highlightMoveVelocity
55+ if (!animate) {
56+ dashContentList.highlightMoveVelocity = units.gu(4167)
57+ dashContentList.highlightMoveDuration = 0
58+ }
59+
60+ // if the scopes haven't loaded yet, then wait until they are.
61+ if (!scopes.loaded) {
62+ set_current_index = [ index, animate, reset ]
63+ return;
64+ }
65+ set_current_index = undefined;
66+
67+ if (dashContentList.count > index)
68+ {
69+ dashContentList.currentIndex = index
70+
71+ if (reset) {
72+ dashContent.positionedAtBeginning()
73+ }
74+ }
75+
76+ if (!animate) {
77+ dashContentList.highlightMoveDuration = storedMoveDuration
78+ dashContentList.highlightMoveVelocity = storedMoveSpeed
79+ }
80+ }
81+
82+ ListView {
83+ id: dashContentList
84+ objectName: "dashContentList"
85+
86+ interactive: dashContent.scopes.loaded && !currentItem.previewShown && !currentItem.moving
87+
88+ anchors.fill: parent
89+ model: dashContent.model
90+ orientation: ListView.Horizontal
91+ boundsBehavior: Flickable.DragAndOvershootBounds
92+ flickDeceleration: units.gu(625)
93+ maximumFlickVelocity: width * 5
94+ snapMode: ListView.SnapOneItem
95+ highlightMoveDuration: 250
96+ highlightRangeMode: ListView.StrictlyEnforceRange
97+ /* FIXME: workaround rendering issue due to use of ShaderEffectSource in
98+ UbuntuShape. While switching from the home scope to the People scope the
99+ rendering would block midway.
100+ */
101+ cacheBuffer: 2147483647
102+ onMovementStarted: dashContent.movementStarted()
103+ onMovementEnded: dashContent.movementEnded()
104+
105+ // If the number of items is less than the current index, then need to reset to another item.
106+ onCountChanged: {
107+ if (currentIndex >= count)
108+ dashContent.setCurrentScopeAtIndex(count-1, true, true)
109+ }
110+
111+ delegate:
112+ Loader {
113+ width: ListView.view.width
114+ height: ListView.view.height
115+ asynchronous: true
116+ source: scopeMapper.map(scope.id)
117+ objectName: scope.id + " loader"
118+
119+ readonly property bool previewShown: item ? item.previewShown : false
120+ readonly property bool moving: item ? item.moving : false
121+
122+ // these are needed for autopilot tests
123+ readonly property string scopeId: scope.id
124+ readonly property bool isCurrent: ListView.isCurrentItem
125+ readonly property bool isLoaded: status == Loader.Ready
126+
127+ onLoaded: {
128+ item.scope = Qt.binding(function() { return scope })
129+ item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
130+ item.searchHistory = Qt.binding(function() { return shell.searchHistory })
131+ dashContentList.movementStarted.connect(item.movementStarted)
132+ dashContent.positionedAtBeginning.connect(item.positionedAtBeginning)
133+ dashContent.scopeLoaded(item.scope.id)
134+ }
135+ Connections {
136+ target: item
137+ ignoreUnknownSignals: true
138+ onEndReached: contentEndReached()
139+ onPreviewShownChanged: {
140+ if (item.previewShown) {
141+ dashContent.previewShown()
142+ }
143+ }
144+ }
145+
146+ Component.onDestruction: active = false
147+ }
148+ }
149+}
Dash/DashHome.qmlnew file+39
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Utils 0.1
20+import "../Components"
21+import "../Components/ListItems"
22+import "Apps"
23+
24+GenericScopeView {
25+ id: root
26+ objectName: "DashHome"
27+
28+ SearchableResultModel {
29+ id: appsModel
30+
31+ model: FrequentlyUsedAppsModel {}
32+ filterRole: 3
33+ searchQuery: root.scope.searchQuery
34+ }
35+
36+ onScopeChanged: {
37+ root.scope.categories.overrideResults("applications.scope", appsModel);
38+ }
39+}
Dash/DashPreview.qmlnew file+205
@@ -0,0 +1,205 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: root
22+
23+ property int keyboardSize: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
24+ property var previewData
25+ property alias showProcessingAction: waitingForActionMouseArea.enabled
26+
27+ property real previewWidthRatio: 0.5
28+
29+ property Component previewImages
30+ property Component header
31+ property Component actions
32+ property Component description
33+ property Component ratings
34+
35+ readonly property bool narrowMode: width <= height * 1.5
36+ readonly property int columnWidth: narrowMode ? contentRow.width : (contentRow.width / 3) - contentRow.spacing
37+ readonly property int contentSpacing: units.gu(3)
38+
39+ clip: true
40+
41+ function ensureVisible(item) {
42+ var o = leftFlickable.mapFromItem(item, 0, 0, item.width, item.height);
43+ var keyboardY = shell.height - root.keyboardSize;
44+ if ((o.y + o.height) > keyboardY) {
45+ leftFlickable.contentY += o.y + o.height - keyboardY;
46+ }
47+ }
48+
49+ Connections {
50+ target: shell.applicationManager
51+ onMainStageFocusedApplicationChanged: {
52+ root.close();
53+ }
54+ onSideStageFocusedApplicationChanged: {
55+ root.close();
56+ }
57+ }
58+
59+ MouseArea {
60+ anchors.fill: parent
61+ }
62+
63+ Row {
64+ id: contentRow
65+ anchors {
66+ left: parent.left
67+ top: parent.top
68+ right: parent.right
69+ bottom: parent.bottom
70+ topMargin: root.contentSpacing
71+ leftMargin: root.contentSpacing
72+ rightMargin: root.contentSpacing
73+ }
74+ height: childrenRect.height
75+
76+ spacing: units.gu(2)
77+
78+
79+ Flickable {
80+ id: leftFlickable
81+ objectName: "leftFlickable"
82+ anchors {
83+ top: parent.top
84+ bottom: parent.bottom
85+ }
86+ width: root.columnWidth
87+ contentHeight: leftColumn.height + root.contentSpacing
88+ anchors.bottomMargin: root.keyboardSize
89+ clip: true
90+
91+ Behavior on contentY { NumberAnimation { duration: 300 } }
92+
93+ Column {
94+ id: leftColumn
95+ objectName: "leftColumn"
96+ height: childrenRect.height
97+ spacing: root.contentSpacing
98+ anchors {
99+ left: parent.left
100+ right: parent.right
101+ }
102+ }
103+ }
104+
105+ Flickable {
106+ id: centerFlickable
107+ anchors {
108+ top: parent.top
109+ bottom: parent.bottom
110+ }
111+ width: root.columnWidth
112+ contentHeight: centerColumn.height
113+ clip: true
114+
115+ Column {
116+ id: centerColumn
117+ objectName: "centerColumn"
118+ height: childrenRect.height
119+ anchors {
120+ left: parent.left
121+ right: parent.right
122+ }
123+ spacing: root.contentSpacing
124+ }
125+ }
126+
127+ Flickable {
128+ id: rightFlickable
129+ anchors {
130+ top: parent.top
131+ bottom: parent.bottom
132+ }
133+ width: root.columnWidth
134+ contentHeight: rightColumn.height
135+ clip: true
136+
137+ Column {
138+ id: rightColumn
139+ objectName: "rightColumn"
140+ height: childrenRect.height
141+ anchors {
142+ left: parent.left
143+ right: parent.right
144+ }
145+ }
146+ }
147+ }
148+
149+ Loader {
150+ id: previewImageLoader
151+ parent: leftColumn
152+ sourceComponent: root.previewImages
153+ anchors {
154+ left: parent.left
155+ right: parent.right
156+ }
157+ }
158+
159+ Loader {
160+ id: ratingsLoader
161+ parent: root.narrowMode ? leftColumn : rightColumn
162+ anchors {
163+ left: parent.left
164+ right: parent.right
165+ }
166+ sourceComponent: root.ratings
167+ }
168+
169+ Loader {
170+ id: descriptionLoader
171+ parent: root.narrowMode ? leftColumn : centerColumn
172+ anchors {
173+ left: parent.left
174+ right: parent.right
175+ }
176+ sourceComponent: root.description
177+ }
178+
179+ Loader {
180+ id: actionsLoader
181+ parent: root.narrowMode ? leftColumn : centerColumn
182+ anchors {
183+ left: parent.left
184+ right: parent.right
185+ }
186+ sourceComponent: root.actions
187+ }
188+
189+ Loader {
190+ id: headerLoader
191+ parent: root.narrowMode ? leftColumn : centerColumn
192+ anchors {
193+ left: parent.left
194+ right: parent.right
195+ }
196+ sourceComponent: root.header
197+ }
198+
199+ MouseArea {
200+ id: waitingForActionMouseArea
201+ objectName: "waitingForActionMouseArea"
202+ anchors.fill: parent
203+ enabled: false
204+ }
205+}
tests/mocks/Ubuntu/SystemSettings/Diagnostics/MockDiagnostics.qml → Dash/DashPreviewPlaceholder.qmlrenamed+7−6
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,11 +14,12 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
18
19
19−Item {
20+DashPreview {
20− property bool reportCrashes: true
21+ ActivityIndicator {
21− function setReportCrashes(report) {
22+ anchors.centerIn: parent
22− reportCrashes = report;
23+ running: true
23 }
24 }
24}
25}
Dash/Generic/FlatTileStyle.qmlnew file+79
@@ -0,0 +1,79 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: tile
22+
23+ property bool disabled: false
24+
25+ anchors.fill: parent
26+
27+ Image {
28+ id: icon
29+ objectName: "image"
30+ width: styledItem.imageWidth
31+ height: styledItem.imageHeight
32+
33+ anchors.horizontalCenter: parent.horizontalCenter
34+
35+ sourceSize { width: width; height: height }
36+ asynchronous: true
37+ cache: false
38+ source: styledItem.source
39+ fillMode: styledItem.fillMode
40+ opacity: tile.disabled ? 0.3 : 1.0
41+ horizontalAlignment: Image.AlignHCenter
42+ verticalAlignment: Image.AlignVCenter
43+ }
44+
45+ UbuntuShape {
46+ id: borderPressed
47+ objectName: "borderPressed"
48+
49+ anchors.fill: icon
50+ radius: "medium"
51+ borderSource: "radius_pressed.sci"
52+ opacity: styledItem.pressed ? 1.0 : 0.0
53+ Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
54+ }
55+
56+ Label {
57+ id: label
58+ objectName: "label"
59+ anchors {
60+ baseline: icon.bottom
61+ baselineOffset: units.gu(2)
62+ left: parent.left
63+ right: parent.right
64+ leftMargin: units.gu(1)
65+ rightMargin: units.gu(1)
66+ }
67+
68+ color: Theme.palette.selected.backgroundText
69+ opacity: 0.9
70+ style: Text.Raised
71+ styleColor: "black"
72+ fontSize: "small"
73+ elide: Text.ElideMiddle
74+ horizontalAlignment: styledItem.horizontalAlignment
75+ text: styledItem.text
76+ wrapMode: Text.Wrap
77+ maximumLineCount: styledItem.maximumLineCount
78+ }
79+}
Dash/Generic/GenericCarousel.qmlnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+
21+Carousel {
22+ id: genericCarousel
23+
24+ tileAspectRatio: 198 / 288
25+ minimumTileWidth: units.gu(13)
26+ itemComponent: carouselDelegateGeneric
27+ selectedItemScaleFactor: 1.14
28+ cacheBuffer: 1404 // 18px * 13gu * 6
29+ height: implicitHeight + units.gu(6)
30+
31+ Component {
32+ id: carouselDelegateGeneric
33+
34+ BaseCarouselDelegate {
35+ id: item
36+
37+ UbuntuShape {
38+ anchors.fill: parent
39+ radius: "medium"
40+ borderSource: ""
41+ image: Image {
42+ asynchronous: true
43+ sourceSize { width: item.width; height: item.height }
44+ source: model ? model.icon : ""
45+ }
46+ }
47+
48+ BorderImage {
49+ anchors.centerIn: parent
50+ opacity: 0.6
51+ source: "../../Components/graphics/non-selected.sci"
52+ width: parent.width + units.gu(1.5)
53+ height: parent.height + units.gu(1.5)
54+ }
55+ }
56+ }
57+}
Dash/Generic/GenericFilterGrid.qmlnew file+52
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+
20+FilterGrid {
21+ id: filtergrid
22+
23+ minimumHorizontalSpacing: units.gu(0.5)
24+ delegateWidth: units.gu(11)
25+ delegateHeight: units.gu(9.5)
26+ verticalSpacing: units.gu(2)
27+
28+ property int iconWidth: units.gu(8)
29+ property int iconHeight: units.gu(7.5)
30+
31+ signal clicked(int index, var model, real itemY)
32+ signal pressAndHold(int index, var model, real itemY)
33+
34+ delegate: Tile {
35+ id: tile
36+ objectName: "delegate" + index
37+ width: filtergrid.cellWidth
38+ height: filtergrid.cellHeight
39+ text: model.title
40+ imageWidth: filtergrid.iconWidth
41+ imageHeight: filtergrid.iconHeight
42+ source: model.icon
43+
44+ onClicked: {
45+ filtergrid.clicked(index, filtergrid.model, tile.y)
46+ }
47+
48+ onPressAndHold: {
49+ filtergrid.pressAndHold(index, filtergrid.model, tile.y)
50+ }
51+ }
52+}
Dash/Generic/GenericFilterGridPotrait.qmlnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+
20+GenericFilterGrid {
21+ id: filtergrid
22+
23+ minimumHorizontalSpacing: units.gu(0.5)
24+ delegateWidth: units.gu(11)
25+ delegateHeight: units.gu(18)
26+ verticalSpacing: units.gu(2)
27+
28+ iconWidth: (width / columns) * 0.8
29+ iconHeight: iconWidth * 16 / 11
30+}
Dash/Generic/GenericPreview.qmlnew file+196
@@ -0,0 +1,196 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItems
20+import Ubuntu.DownloadDaemonListener 0.1
21+import "../../Components"
22+import ".."
23+import "../Previews"
24+
25+DashPreview {
26+ id: genericPreview
27+
28+ previewImages: previewImagesComponent
29+ header: headerComponent
30+ actions: (previewData.infoMap !== undefined && previewData.infoMap["show_progressbar"]) ? progressComponent : actionsComponent
31+ description: descriptionComponent
32+
33+ Component {
34+ id: previewImagesComponent
35+
36+ LazyImage {
37+ objectName: "genericPreviewImage"
38+ anchors {
39+ left: parent.left
40+ right: parent.right
41+ }
42+ scaleTo: "width"
43+ source: genericPreview.previewData.image
44+ initialHeight: width
45+ }
46+ }
47+
48+ Component {
49+ id: headerComponent
50+ Header {
51+ title: previewData.title
52+ subtitle: previewData.subtitle
53+ }
54+ }
55+
56+ Component {
57+ id: actionsComponent
58+
59+ Column {
60+ id: buttonList
61+ spacing: units.gu(1)
62+ Repeater {
63+ objectName: "buttonList"
64+ model: previewData.actions
65+
66+ delegate: Button {
67+ objectName: "button" + index
68+ width: parent.width
69+ height: buttonList.buttonHeight
70+ color: Theme.palette.selected.foreground
71+ text: modelData.displayName
72+ iconSource: modelData.iconHint
73+ iconPosition: "right"
74+ onClicked: {
75+ previewData.execute(modelData.id, { })
76+ genericPreview.showProcessingAction = true;
77+ }
78+ }
79+ }
80+ }
81+ }
82+
83+ Component {
84+ id: progressComponent
85+
86+ ProgressBar {
87+ id: progressBar
88+ objectName: "progressBar"
89+ value: 0
90+ maximumValue: 100
91+ height: units.gu(5)
92+
93+ property var model: previewData.actions
94+
95+ DownloadTracker {
96+ service: "com.canonical.applications.Downloader"
97+ dbusPath: previewData.infoMap["progressbar_source"] ? previewData.infoMap["progressbar_source"].value : ""
98+
99+ onProgress: {
100+ var percentage = parseInt(received * 100 / total);
101+ progressBar.value = percentage;
102+ }
103+
104+ onFinished: {
105+ previewData.execute(progressBar.model[0].id, { })
106+ }
107+
108+ onError: {
109+ previewData.execute(progressBar.model[1].id, { "error": error });
110+ }
111+ }
112+
113+ }
114+ }
115+
116+ Component {
117+ id: descriptionComponent
118+ Column {
119+ spacing: units.gu(2)
120+
121+ Label {
122+ id: descriptionLabel
123+ anchors { left: parent.left; right: parent.right }
124+ visible: text != ""
125+ fontSize: "small"
126+ opacity: 0.6
127+ color: "white"
128+ text: previewData.description.replace(/[\r\n]/g, "<br />")
129+ style: Text.Raised
130+ styleColor: "black"
131+ wrapMode: Text.WordWrap
132+ textFormat: Text.RichText
133+ // FIXME: workaround for https://bugreports.qt-project.org/browse/QTBUG-33020
134+ onWidthChanged: { wrapMode = Text.NoWrap; wrapMode = Text.WordWrap }
135+ }
136+
137+ Column {
138+ objectName: "infoHintColumn"
139+ anchors {
140+ left: parent.left
141+ right: parent.right
142+ }
143+ Repeater {
144+ objectName: "infoHintRepeater"
145+ model: previewData.infoHints
146+
147+ delegate: Item {
148+ objectName: "infoHintItem" + index
149+ width: parent.width
150+ height: units.gu(5)
151+ Row {
152+ width: parent.width
153+ spacing: units.gu(1)
154+ property int columnWidth: (width - spacing) / 2
155+ anchors.verticalCenter: parent.verticalCenter
156+
157+ Label {
158+ objectName: "displayNameLabel"
159+ visible: valueLabel.visible
160+ fontSize: "small"
161+ opacity: 0.9
162+ color: "white"
163+ horizontalAlignment: Text.AlignLeft
164+ width: parent.columnWidth
165+ text: modelData.displayName
166+ style: Text.Raised
167+ styleColor: "black"
168+ }
169+ Label {
170+ id: valueLabel
171+ objectName: "valueLabel"
172+ visible: modelData.value != ""
173+ fontSize: "small"
174+ opacity: 0.6
175+ color: "white"
176+ horizontalAlignment: Text.AlignRight
177+ width: parent.columnWidth
178+ text: modelData.value ? modelData.value : ""
179+ style: Text.Raised
180+ styleColor: "black"
181+ wrapMode: Text.WordWrap
182+ }
183+ }
184+ ListItems.ThinDivider {
185+ anchors {
186+ left: parent.left
187+ bottom: parent.bottom
188+ right: parent.right
189+ }
190+ }
191+ }
192+ }
193+ }
194+ }
195+ }
196+}
Dash/Generic/WeatherFilterGrid.qmlnew file+47
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+
21+GenericFilterGrid {
22+ id: filtergrid
23+
24+ delegateHeight: units.gu(11.5)
25+
26+ delegate: Tile {
27+ id: tile
28+ objectName: "delegate" + index
29+ width: filtergrid.cellWidth
30+ height: filtergrid.cellHeight
31+ text: model.title
32+ imageWidth: filtergrid.iconWidth
33+ imageHeight: filtergrid.iconHeight
34+ source: model.icon
35+ maximumLineCount: 2
36+
37+ style: FlatTileStyle {}
38+
39+ onClicked: {
40+ filtergrid.clicked(index, filtergrid.model, tile.y)
41+ }
42+
43+ onPressAndHold: {
44+ filtergrid.pressAndHold(index, filtergrid.model, tile.y)
45+ }
46+ }
47+}
Dash/GenericScopeView.qmlnew file+529
@@ -0,0 +1,529 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+import "../Components/ListItems" as ListItems
21+
22+ScopeView {
23+ id: scopeView
24+ readonly property alias previewShown: previewListView.onScreen
25+ property bool enableHeightBehaviorOnNextCreation: false
26+
27+ moving: categoryView.moving
28+
29+ onIsCurrentChanged: {
30+ pageHeader.resetSearch();
31+ previewListView.open = false;
32+ }
33+
34+ onMovementStarted: categoryView.showHeader()
35+
36+ onPositionedAtBeginning: categoryView.positionAtBeginning()
37+
38+ Binding {
39+ target: scopeView.scope
40+ property: "searchQuery"
41+ value: pageHeader.searchQuery
42+ }
43+
44+ Binding {
45+ target: pageHeader
46+ property: "searchQuery"
47+ value: scopeView.scope.searchQuery
48+ }
49+
50+ Connections {
51+ target: panel
52+ onSearchClicked: if (isCurrent) {
53+ pageHeader.triggerSearch()
54+ categoryView.showHeader()
55+ }
56+ }
57+
58+ Connections {
59+ target: scopeView.scope
60+ onShowDash: previewListView.open = false;
61+ onHideDash: previewListView.open = false;
62+ }
63+
64+ ScopeListView {
65+ id: categoryView
66+ objectName: "categoryListView"
67+ anchors.fill: parent
68+ model: scopeView.categories
69+ forceNoClip: previewListView.onScreen
70+
71+ onAtYEndChanged: if (atYEnd) endReached()
72+ onMovingChanged: if (moving && atYEnd) endReached()
73+
74+ property string expandedCategoryId: ""
75+ signal correctExpandedCategory();
76+
77+ Behavior on contentY {
78+ enabled: previewListView.open
79+ UbuntuNumberAnimation {}
80+ }
81+
82+ delegate: ListItems.Base {
83+ id: baseItem
84+ highlightWhenPressed: false
85+
86+ readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
87+ readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
88+ readonly property string category: categoryId
89+
90+ Loader {
91+ id: rendererLoader
92+ anchors {
93+ top: parent.top
94+ left: parent.left
95+ right: parent.right
96+ }
97+
98+ source: getRenderer(model.renderer, model.contentType, model.rendererHint)
99+
100+ onLoaded: {
101+ if (item.enableHeightBehavior !== undefined && item.enableHeightBehaviorOnNextCreation !== undefined) {
102+ item.enableHeightBehavior = scopeView.enableHeightBehaviorOnNextCreation;
103+ scopeView.enableHeightBehaviorOnNextCreation = false;
104+ }
105+ if (source.toString().indexOf("Apps/RunningApplicationsGrid.qml") != -1) {
106+ // TODO: the running apps grid doesn't support standard scope results model yet
107+ item.firstModel = Qt.binding(function() { return results.firstModel })
108+ item.secondModel = Qt.binding(function() { return results.secondModel })
109+ item.canEnableTerminationMode = Qt.binding(function() { return scopeView.isCurrent })
110+ } else {
111+ item.model = Qt.binding(function() { return results })
112+ }
113+ item.objectName = Qt.binding(function() { return categoryId })
114+ if (item.expandable) {
115+ var shouldFilter = categoryId != categoryView.expandedCategoryId;
116+ if (shouldFilter != item.filter) {
117+ item.filter = shouldFilter;
118+ }
119+ }
120+ updateDelegateCreationRange();
121+ }
122+
123+ Component.onDestruction: {
124+ if (item.enableHeightBehavior !== undefined && item.enableHeightBehaviorOnNextCreation !== undefined) {
125+ scopeView.enableHeightBehaviorOnNextCreation = item.enableHeightBehaviorOnNextCreation;
126+ }
127+ }
128+
129+ Connections {
130+ target: rendererLoader.item
131+ onClicked: {
132+ // Prepare the preview in case activate() triggers a preview only
133+ effect.positionPx = mapToItem(categoryView, 0, itemY).y
134+ previewListView.categoryId = categoryId
135+ previewListView.categoryDelegate = rendererLoader.item
136+ previewListView.model = model;
137+ previewListView.init = true;
138+ previewListView.currentIndex = index;
139+
140+ var item = model.get(index);
141+
142+ if ((scopeView.scope.id == "applications.scope" && categoryId == "installed")
143+ || (scopeView.scope.id == "home.scope" && categoryId == "applications.scope")) {
144+ scopeView.scope.activate(item.uri, item.icon, item.category, 0, item.mimetype, item.title,
145+ item.comment, item.dndUri, item.metadata)
146+ } else {
147+ previewListView.open = true
148+
149+ scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
150+ item.comment, item.dndUri, item.metadata)
151+ }
152+ }
153+ onPressAndHold: {
154+ effect.positionPx = mapToItem(categoryView, 0, itemY).y
155+ previewListView.categoryId = categoryId
156+ previewListView.categoryDelegate = rendererLoader.item
157+ previewListView.model = model;
158+ previewListView.init = true;
159+ previewListView.currentIndex = index;
160+ previewListView.open = true
161+
162+ var item = model.get(index)
163+ scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
164+ item.comment, item.dndUri, item.metadata)
165+ }
166+ }
167+ Connections {
168+ target: categoryView
169+ onExpandedCategoryIdChanged: {
170+ collapseAllButExpandedCategory();
171+ }
172+ onCorrectExpandedCategory: {
173+ collapseAllButExpandedCategory();
174+ }
175+ function collapseAllButExpandedCategory() {
176+ var item = rendererLoader.item;
177+ if (item.expandable) {
178+ var shouldFilter = categoryId != categoryView.expandedCategoryId;
179+ if (shouldFilter != item.filter) {
180+ // If the filter animation will be seen start it, otherwise, just flip the switch
181+ var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
182+ var growingVisible = !shouldFilter && y + height < categoryView.height;
183+ if (!previewListView.open || !shouldFilter) {
184+ if (shrinkingVisible || growingVisible) {
185+ item.startFilterAnimation(shouldFilter)
186+ } else {
187+ item.filter = shouldFilter;
188+ }
189+ if (!shouldFilter && !previewListView.open) {
190+ categoryView.maximizeVisibleArea(index, item.uncollapsedHeight);
191+ }
192+ }
193+ }
194+ }
195+ }
196+ onContentYChanged: rendererLoader.updateDelegateCreationRange();
197+ onHeightChanged: rendererLoader.updateDelegateCreationRange();
198+ }
199+
200+ function updateDelegateCreationRange() {
201+ // Do not update the range if we are overshooting up or down, since we'll come back
202+ // to the stable position and delete/create items without any reason
203+ if (categoryView.contentY < categoryView.originY) {
204+ return;
205+ } else if (categoryView.contentY + categoryView.height > categoryView.contentHeight) {
206+ return;
207+ }
208+
209+ if (item.hasOwnProperty("delegateCreationBegin")) {
210+ if (baseItem.y + baseItem.height <= 0) {
211+ // Not visible (item at top of the list)
212+ item.delegateCreationBegin = baseItem.height
213+ item.delegateCreationEnd = baseItem.height
214+ } else if (baseItem.y >= categoryView.height) {
215+ // Not visible (item at bottom of the list)
216+ item.delegateCreationBegin = 0
217+ item.delegateCreationEnd = 0
218+ } else {
219+ item.delegateCreationBegin = Math.max(-baseItem.y, 0)
220+ item.delegateCreationEnd = Math.min(categoryView.height + item.delegateCreationBegin, baseItem.height)
221+ }
222+ }
223+ }
224+ }
225+ }
226+
227+ sectionProperty: "name"
228+ sectionDelegate: ListItems.Header {
229+ property var delegate: categoryView.item(delegateIndex)
230+ width: categoryView.width
231+ text: section
232+ image: {
233+ if (delegate && delegate.expandable)
234+ return delegate.filtered ? "graphics/header_handlearrow.png" : "graphics/header_handlearrow2.png"
235+ return "";
236+ }
237+ onClicked: {
238+ if (categoryView.expandedCategoryId != delegate.category)
239+ categoryView.expandedCategoryId = delegate.category;
240+ else
241+ categoryView.expandedCategoryId = "";
242+ }
243+ }
244+ pageHeader: PageHeader {
245+ id: pageHeader
246+ objectName: "pageHeader"
247+ width: categoryView.width
248+ text: scopeView.scope.name
249+ searchEntryEnabled: true
250+ scope: scopeView.scope
251+ }
252+ }
253+
254+ function getDefaultRendererId(contentType) {
255+ switch (contentType) {
256+ default: return "grid";
257+ }
258+ }
259+
260+ function getRenderer(rendererId, contentType, rendererHint) {
261+ if (rendererId == "default") {
262+ rendererId = getDefaultRendererId(contentType);
263+ }
264+ switch (rendererId) {
265+ case "grid": {
266+ switch (contentType) {
267+ case "video": return "Video/VideoFilterGrid.qml";
268+ case "music": return "Music/MusicFilterGrid.qml";
269+ case "apps": {
270+ if (rendererHint == "toggled")
271+ return "Apps/DashPluginFilterGrid.qml";
272+ else
273+ return "Generic/GenericFilterGrid.qml";
274+ }
275+ case "weather": return "Generic/WeatherFilterGrid.qml";
276+ default: return "Generic/GenericFilterGrid.qml";
277+ }
278+ }
279+ case "carousel": {
280+ switch (contentType) {
281+ case "music": return "Music/MusicCarousel.qml";
282+ default: return "Generic/GenericCarousel.qml";
283+ }
284+ }
285+ case "special": {
286+ switch (contentType) {
287+ case "apps": return "Apps/RunningApplicationsGrid.qml";
288+ default: return "Generic/GenericFilterGrid.qml";
289+ }
290+ }
291+ default: return "Generic/GenericFilterGrid.qml";
292+ }
293+ }
294+
295+ OpenEffect {
296+ id: effect
297+ objectName: "openEffect"
298+ anchors {
299+ fill: parent
300+ bottomMargin: -bottomOverflow
301+ }
302+ sourceItem: categoryView
303+
304+ enabled: gap > 0.0
305+
306+ topGapPx: (1 - gap) * positionPx
307+ topOpacity: (1 - gap * 1.2)
308+ bottomGapPx: positionPx + gap * (targetBottomGapPx - positionPx)
309+ bottomOverflow: units.gu(20)
310+ live: !expansionAnimation.running
311+
312+ property int targetBottomGapPx: height - units.gu(8) - bottomOverflow
313+ property real gap: previewListView.open ? 1.0 : 0.0
314+
315+ Behavior on gap {
316+ NumberAnimation {
317+ id: expansionAnimation
318+ duration: 200
319+ easing.type: Easing.InOutQuad
320+ onRunningChanged: {
321+ if (!previewListView.open && !running) {
322+ previewListView.onScreen = false
323+ }
324+ }
325+ }
326+ }
327+ Behavior on positionPx {
328+ enabled: previewListView.open
329+ UbuntuNumberAnimation {}
330+ }
331+ }
332+
333+ Connections {
334+ target: scopeView.scope
335+ onPreviewReady: {
336+ if (previewListView.init) {
337+ // Preview was triggered because of a click on the item. Need to expand now.
338+ if (!previewListView.open) {
339+ previewListView.open = true
340+ }
341+
342+ var index = previewListView.currentIndex
343+ previewListView.currentIndex = -1
344+ previewListView.currentIndex = index
345+ previewListView.init = false
346+ }
347+ previewListView.currentItem.previewData = preview
348+ }
349+ }
350+
351+ PreviewDelegateMapper {
352+ id: previewDelegateMapper
353+ }
354+
355+ ListView {
356+ id: previewListView
357+ objectName: "previewListView"
358+ height: effect.bottomGapPx - effect.topGapPx
359+ anchors {
360+ top: parent.top
361+ topMargin: effect.topGapPx
362+ left: parent.left
363+ right: parent.right
364+ }
365+ orientation: ListView.Horizontal
366+ highlightRangeMode: ListView.StrictlyEnforceRange
367+ snapMode: ListView.SnapOneItem
368+ boundsBehavior: Flickable.DragAndOvershootBounds
369+ highlightMoveDuration: 250
370+ flickDeceleration: units.gu(625)
371+ maximumFlickVelocity: width * 5
372+ cacheBuffer: 0
373+
374+ // To be set before opening the preview
375+ property string categoryId: ""
376+ property var categoryDelegate
377+
378+ // because the ListView is built asynchronous, setting the
379+ // currentIndex directly won't work. We need to refresh it
380+ // when the first preview is ready to be displayed.
381+ property bool init: true
382+
383+ onCurrentIndexChanged: {
384+ var row = Math.floor(currentIndex / categoryDelegate.columns);
385+ if (categoryDelegate.collapsedRowCount <= row) {
386+ categoryView.expandedCategoryId = categoryId
387+ }
388+
389+ if (open) {
390+ categoryDelegate.highlightIndex = currentIndex
391+ }
392+
393+ if (!init && model !== undefined) {
394+ var item = model.get(currentIndex)
395+ scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
396+ }
397+
398+ var itemY = categoryView.contentItem.mapFromItem(categoryDelegate.currentItem).y;
399+ var newContentY = itemY - effect.positionPx - categoryDelegate.verticalSpacing;
400+ var effectAdjust = effect.positionPx;
401+ if (newContentY < 0) {
402+ effectAdjust += newContentY;
403+ newContentY = 0;
404+ }
405+ if (newContentY > Math.max(0, categoryView.contentHeight - categoryView.height)) {
406+ effectAdjust += -(categoryView.contentHeight - categoryView.height) + newContentY
407+ newContentY = categoryView.contentHeight - categoryView.height;
408+ }
409+
410+ effect.positionPx = effectAdjust;
411+ categoryView.contentY = newContentY - categoryView.originY;
412+ }
413+
414+ property bool open: false
415+ property bool onScreen: false
416+
417+ onOpenChanged: {
418+ if (open) {
419+ onScreen = true;
420+ categoryDelegate.highlightIndex = currentIndex;
421+ pageHeader.unfocus();
422+ } else {
423+ // Cancel any pending preview requests or actions
424+ if (previewListView.currentItem.previewData !== undefined) {
425+ previewListView.currentItem.previewData.cancelAction();
426+ }
427+ scopeView.scope.cancelActivation();
428+ model = undefined;
429+ categoryView.correctExpandedCategory();
430+ categoryDelegate.highlightIndex = -1;
431+ }
432+ }
433+
434+ Rectangle {
435+ anchors.fill: parent
436+ color: Qt.rgba(0, 0, 0, .3)
437+ z: -1
438+ }
439+
440+ delegate: Loader {
441+ id: previewLoader
442+ objectName: "previewLoader" + index
443+ height: previewListView.height
444+ width: previewListView.width
445+ asynchronous: true
446+ source: previewListView.onScreen ?
447+ (previewData !== undefined ? previewDelegateMapper.map(previewData.rendererName) : "DashPreviewPlaceholder.qml") : ""
448+
449+ onPreviewDataChanged: {
450+ if (previewData !== undefined && source.toString().indexOf("DashPreviewPlaceholder.qml") != -1) {
451+ previewLoader.opacity = 0;
452+ }
453+ }
454+
455+ onSourceChanged: {
456+ if (previewData !== undefined) {
457+ fadeIn.start()
458+ }
459+ }
460+
461+ PropertyAnimation {
462+ id: fadeIn
463+ target: previewLoader
464+ property: "opacity"
465+ from: 0.0
466+ to: 1.0
467+ duration: UbuntuAnimation.BriskDuration
468+ }
469+
470+ property var previewData
471+ property bool valid: item !== null
472+
473+ onLoaded: {
474+ if (previewListView.onScreen && previewData !== undefined) {
475+ item.previewData = Qt.binding(function() { return previewData })
476+ }
477+ }
478+
479+ Connections {
480+ ignoreUnknownSignals: true
481+ target: item
482+ onClose: {
483+ previewListView.open = false
484+ }
485+ }
486+
487+ function closePreviewSpinner() {
488+ if(item) {
489+ item.showProcessingAction = false;
490+ }
491+ }
492+ }
493+ }
494+
495+ Image {
496+ objectName: "pointerArrow"
497+ anchors {
498+ top: previewListView.bottom
499+ left: parent.left
500+ leftMargin: previewListView.categoryDelegate !== undefined && previewListView.categoryDelegate.currentItem ?
501+ previewListView.categoryDelegate.currentItem.center + (-width + margins) / 2 : 0
502+
503+ Behavior on leftMargin {
504+ SmoothedAnimation {
505+ duration: UbuntuAnimation.FastDuration
506+ }
507+ }
508+ }
509+ height: units.gu(1)
510+ width: units.gu(2)
511+ property int margins: previewListView.categoryDelegate ? previewListView.categoryDelegate.margins : 0
512+ opacity: previewListView.open ? .5 : 0
513+
514+ source: "graphics/tooltip_arrow.png"
515+ }
516+
517+ // TODO: Move as InverseMouseArea to DashPreview
518+ MouseArea {
519+ objectName: "closePreviewMouseArea"
520+ enabled: previewListView.onScreen
521+ anchors {
522+ fill: parent
523+ topMargin: effect.bottomGapPx
524+ }
525+ onClicked: {
526+ previewListView.open = false;
527+ }
528+ }
529+}
Dash/Movie/MoviePreview.qmlnew file+71
@@ -0,0 +1,71 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import ".."
20+import "../Generic"
21+import "../../Components"
22+import "../Previews"
23+
24+GenericPreview {
25+ id: root
26+
27+ property bool ready: previewData ? true : false
28+ property url url: ready ? previewData.image : ""
29+
30+ previewImages: previewImageComponent
31+ header: headerComponent
32+
33+ Component {
34+ id: previewImageComponent
35+ LazyImage {
36+ anchors.left: parent.left
37+ anchors.right: parent.right
38+ scaleTo: "width"
39+ visible: height > 0
40+ source: root.url
41+ initialHeight: width * 10 / 16
42+
43+ Image {
44+ objectName: "playButton"
45+ anchors.centerIn: parent
46+ readonly property bool bigButton: parent.width > units.gu(40)
47+ width: bigButton ? units.gu(8) : units.gu(4.5)
48+ height: width
49+ source: "../graphics/play_button%1%2.png".arg(previewImageMouseArea.pressed ? "_active" : "").arg(bigButton ? "_big" : "")
50+ }
51+
52+ MouseArea {
53+ id: previewImageMouseArea
54+ anchors.fill: parent
55+ onClicked: {
56+ Qt.openUrlExternally(previewData.result.uri);
57+ }
58+ }
59+ }
60+ }
61+
62+ Component {
63+ id: headerComponent
64+ Header {
65+ title: previewData.title
66+ rating: Math.round(previewData.rating * 10)
67+ reviews: previewData.numRatings
68+ rated: previewData.infoMap["rated"] ? previewData.infoMap["rated"].value : 0
69+ }
70+ }
71+}
qml/Greeter/LoginAreaContainer.qml → Dash/Music/CarouselDelegateMusic.qmlrenamed+21−17
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,25 +14,29 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19+import "../../Components"
19
20
20−Item {
21+BaseCarouselDelegate {
21− BorderImage {
22+ id: item
22− anchors {
23− fill: parent
24− topMargin: -units.gu(3)
25− leftMargin: -units.gu(1.5)
26− rightMargin: -units.gu(1.5)
27− bottomMargin: -units.gu(1.5)
28− }
29− source: "../graphics/dropshadow2gu.sci"
30− opacity: 0
31− }
32
23
33 UbuntuShape {
24 UbuntuShape {
34 anchors.fill: parent
25 anchors.fill: parent
35− aspect: UbuntuShape.Flat
26+ radius: "medium"
36− backgroundColor: "transparent"
27+ borderSource: ""
28+ image: Image {
29+ asynchronous: true
30+ sourceSize { width: item.width; height: item.height }
31+ source: model ? model.icon : ""
32+ }
33+ }
34+
35+ BorderImage {
36+ anchors.centerIn: parent
37+ opacity: 0.6
38+ source: "../../Components/graphics/non-selected.sci"
39+ width: parent.width + units.gu(1.5)
40+ height: parent.height + units.gu(1.5)
37 }
41 }
38}
42}
Dash/Music/MusicCarousel.qmlnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+
20+Carousel {
21+ id: musicCarousel
22+ tileAspectRatio: 1
23+ minimumTileWidth: units.gu(13)
24+ itemComponent: carouselDelegateMusic
25+ selectedItemScaleFactor: 1.2
26+ cacheBuffer: 1404 // 18px * 13gu * 6
27+ height: implicitHeight + units.gu(6)
28+
29+ Component {
30+ id: carouselDelegateMusic
31+ CarouselDelegateMusic {
32+ }
33+ }
34+}
Dash/Music/MusicFilterGrid.qmlnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+import "../Generic"
20+
21+GenericFilterGrid {
22+ id: filtergrid
23+
24+ delegateWidth: units.gu(11)
25+ delegateHeight: units.gu(16)
26+
27+ iconWidth: units.gu(11)
28+ iconHeight: units.gu(11)
29+
30+ delegate: Tile {
31+ id: tile
32+ objectName: "delegate" + index
33+ width: filtergrid.cellWidth
34+ height: filtergrid.cellHeight
35+ text: model.comment
36+ imageWidth: filtergrid.iconWidth
37+ imageHeight: filtergrid.iconHeight
38+ source: model.icon
39+ maximumLineCount: 2
40+ horizontalAlignment: Text.AlignLeft
41+
42+ style: MusicTileStyle {
43+ artist: model.title
44+ }
45+
46+ onClicked: {
47+ filtergrid.clicked(index, filtergrid.model, tile.y)
48+ }
49+
50+ onPressAndHold: {
51+ filtergrid.pressAndHold(index, filtergrid.model, tile.y)
52+ }
53+ }
54+}
Dash/Music/MusicTileStyle.qmlnew file+102
@@ -0,0 +1,102 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: tile
22+
23+ property alias artist: artistLabel.text
24+
25+ anchors.fill: parent
26+
27+ UbuntuShape {
28+ id: icon
29+ anchors {
30+ top: parent.top
31+ horizontalCenter: parent.horizontalCenter
32+ }
33+ radius: "medium"
34+ width: styledItem.imageWidth
35+ height: styledItem.imageHeight
36+ image: Image {
37+ id: image
38+ objectName: "image"
39+ sourceSize { width: icon.width; height: icon.height }
40+ asynchronous: true
41+ cache: false
42+ source: styledItem.source
43+ fillMode: styledItem.fillMode
44+ horizontalAlignment: Image.AlignHCenter
45+ verticalAlignment: Image.AlignVCenter
46+ }
47+ }
48+
49+ UbuntuShape {
50+ id: borderPressed
51+ objectName: "borderPressed"
52+
53+ anchors.fill: icon
54+ radius: "medium"
55+ borderSource: "radius_pressed.sci"
56+ opacity: styledItem.pressed ? 1.0 : 0.0
57+ Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
58+ }
59+
60+ Label {
61+ id: label
62+ objectName: "label"
63+ anchors {
64+ baseline: icon.bottom
65+ baselineOffset: units.gu(2)
66+ left: icon.left
67+ right: parent.right
68+ rightMargin: units.gu(1)
69+ leftMargin: units.dp(2)
70+ }
71+
72+ color: Theme.palette.selected.backgroundText
73+ opacity: 0.9
74+ style: Text.Raised
75+ styleColor: "black"
76+ fontSize: "small"
77+ font.weight: Font.Bold
78+ elide: Text.ElideRight
79+ horizontalAlignment: styledItem.horizontalAlignment
80+ text: styledItem.text
81+ wrapMode: Text.Wrap
82+ maximumLineCount: styledItem.maximumLineCount
83+ }
84+
85+ Label {
86+ id: artistLabel
87+ anchors {
88+ top: label.bottom
89+ left: label.left
90+ right: label.right
91+ rightMargin: units.gu(1)
92+ }
93+
94+ color: Theme.palette.selected.backgroundText
95+ opacity: 0.9
96+ style: Text.Raised
97+ styleColor: "black"
98+ fontSize: "x-small"
99+ elide: Text.ElideMiddle
100+ horizontalAlignment: styledItem.horizontalAlignment
101+ }
102+}
Dash/PreviewDelegateMapper.qmlnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+QtObject {
20+ property var d: QtObject {
21+ readonly property string genericPreview: "Generic/GenericPreview.qml"
22+ readonly property string appPreview: "Apps/AppPreview.qml"
23+ property var previewDelegateMapping: {"preview-generic": genericPreview,
24+ "preview-application": appPreview,
25+ "preview-movie": "Movie/MoviePreview.qml",
26+ }
27+ }
28+
29+ function map(rendererName) {
30+ var customPreview = d.previewDelegateMapping[rendererName]
31+ if (customPreview != undefined) {
32+ return customPreview
33+ }
34+ console.debug("Renderer "+rendererName+" not found, using preview-generic")
35+ return d.genericPreview
36+ }
37+}
Dash/Previews/Header.qmlnew file+109
@@ -0,0 +1,109 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+
21+Row {
22+ id: root
23+ property alias icon: image.source
24+ property alias title: titleLabel.text
25+ property alias subtitle: subtitleLabel.text
26+ property alias rating: ratingStars.rating
27+ property int rated: 0
28+ property int reviews: 0
29+
30+ spacing: units.gu(2)
31+ height: imageShape.visible ? imageShape.height : contentColumn.height
32+
33+ UbuntuShape {
34+ id: imageShape
35+ width: height
36+ height: Math.max(units.gu(6), contentColumn.height)
37+ visible: image.source.toString().length > 0
38+ image: Image {
39+ id: image
40+ sourceSize { width: imageShape.width; height: imageShape.height }
41+ asynchronous: true
42+ fillMode: Image.PreserveAspectFit
43+ }
44+ }
45+
46+ Column {
47+ id: contentColumn
48+ spacing: units.gu(1)
49+ width: parent.width - x
50+
51+ Label {
52+ id: titleLabel
53+ objectName: "titleLabel"
54+ fontSize: "large"
55+ color: "white"
56+ style: Text.Raised
57+ styleColor: "black"
58+ opacity: .9
59+ width: parent.width
60+ elide: Text.ElideRight
61+ }
62+
63+ Label {
64+ id: subtitleLabel
65+ objectName: "subtitleLabel"
66+ fontSize: "medium"
67+ color: "white"
68+ style: Text.Raised
69+ styleColor: "black"
70+ opacity: .6
71+ visible: text.length > 0
72+ }
73+
74+ Row {
75+ visible: root.rating >= 0
76+ spacing: units.gu(1)
77+
78+ RatingStars {
79+ id: ratingStars
80+ maximumRating: 10
81+ rating: -1
82+ }
83+
84+ Label {
85+ id: ratedLabel
86+ objectName: "ratedLabel"
87+ fontSize: "medium"
88+ color: "white"
89+ style: Text.Raised
90+ styleColor: "black"
91+ opacity: .6
92+ //TRANSLATORS: Number of persons who rated this app/video/whatever
93+ text: i18n.tr("(%1)").arg(root.rated)
94+ }
95+
96+ Label {
97+ id: reviewsLabel
98+ objectName: "reviewsLabel"
99+ fontSize: "medium"
100+ color: "white"
101+ style: Text.Raised
102+ styleColor: "black"
103+ opacity: .6
104+ //TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
105+ text: i18n.tr("%1 review", "%1 reviews", root.reviews).arg(root.reviews)
106+ }
107+ }
108+ }
109+}
Dash/Previews/Reviews.qmlnew file+194
@@ -0,0 +1,194 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItem
20+import "../../Components"
21+
22+Column {
23+ id: root
24+
25+ property var model
26+ property alias textArea: reviewField
27+
28+ signal sendReview(string review)
29+ signal editing
30+
31+ spacing: units.gu(2)
32+ state: ""
33+
34+ states: [
35+ State {
36+ name: ""
37+ PropertyChanges { target: reviewField; width: root.width }
38+ PropertyChanges { target: sendButton; opacity: 0 }
39+ PropertyChanges { target: inverseArea; enabled: false }
40+ },
41+ State {
42+ name: "editing"
43+ PropertyChanges { target: reviewField; width: (root.width - row.spacing - sendButton.width) }
44+ PropertyChanges { target: sendButton; opacity: 1 }
45+ PropertyChanges { target: inverseArea; enabled: true }
46+ }
47+ ]
48+
49+ transitions: [
50+ Transition {
51+ from: ""
52+ to: "editing"
53+ SequentialAnimation {
54+ UbuntuNumberAnimation { target: reviewField; properties: "width"; duration: UbuntuAnimation.SlowDuration }
55+ UbuntuNumberAnimation { target: sendButton; properties: "opacity"; duration: UbuntuAnimation.SlowDuration }
56+ }
57+ },
58+ Transition {
59+ from: "editing"
60+ to: ""
61+ SequentialAnimation {
62+ UbuntuNumberAnimation { target: sendButton; properties: "opacity"; duration: UbuntuAnimation.SlowDuration }
63+ UbuntuNumberAnimation { target: reviewField; properties: "width"; duration: UbuntuAnimation.SlowDuration }
64+ }
65+ }
66+ ]
67+
68+ Label {
69+ fontSize: "medium"
70+ color: "white"
71+ style: Text.Raised
72+ styleColor: "black"
73+ opacity: .9
74+ text: i18n.tr("Add a review")
75+ }
76+
77+ Row {
78+ id: row
79+ spacing: units.gu(1)
80+ width: root.width
81+
82+ // FIXME: needs to react to Qt.inputMethod geometry
83+ TextArea {
84+ id: reviewField
85+ objectName: "reviewField"
86+ placeholderText: i18n.tr("Review")
87+ width: parent.width
88+ verticalAlignment: Text.AlignVCenter
89+ autoSize: true
90+ maximumLineCount: 5
91+
92+ Behavior on height { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
93+
94+ onFocusChanged: {
95+ if(reviewField.focus){
96+ root.state = "editing";
97+ reviewField.selectAll();
98+ root.editing();
99+ }
100+ }
101+
102+ // FIXME: not active when in wide mode
103+ InverseMouseArea {
104+ id: inverseArea
105+ anchors.fill: parent
106+ enabled: false
107+ onPressed: {
108+ reviewField.focus = false;
109+ root.state = "";
110+ }
111+ }
112+ }
113+
114+ Button {
115+ id: sendButton
116+ objectName: "sendButton"
117+ width: units.gu(10)
118+ height: units.gu(4)
119+ anchors.bottom: reviewField.bottom
120+ color: Theme.palette.selected.foreground
121+ text: i18n.tr("Send")
122+ opacity: 0
123+
124+ onClicked: {
125+ root.sendReview(reviewField.text);
126+ reviewField.text = ""
127+ }
128+ }
129+ }
130+
131+ ListItem.ThinDivider {}
132+
133+ Label {
134+ fontSize: "medium"
135+ color: "white"
136+ style: Text.Raised
137+ styleColor: "black"
138+ opacity: .9
139+ text: i18n.tr("Comments:")
140+ }
141+
142+ Repeater {
143+ objectName: "commentsArea"
144+ model: root.model
145+
146+ Column {
147+ anchors { left: parent.left; right: parent.right }
148+
149+ Column {
150+ anchors { left: parent.left; right: parent.right }
151+
152+ Label {
153+ anchors { left: parent.left; right: parent.right }
154+ text: modelData[0]
155+ fontSize: "medium"
156+ color: "white"
157+ opacity: .8
158+ wrapMode: Text.WordWrap
159+ style: Text.Raised
160+ styleColor: "black"
161+ }
162+
163+ Row {
164+ spacing: units.gu(1)
165+
166+ RatingStars {
167+ maximumRating: 10
168+ rating: modelData[1]
169+ }
170+
171+ Label {
172+ text: modelData[2]
173+ fontSize: "medium"
174+ color: Theme.palette.selected.backgroundText
175+ opacity: .6
176+ style: Text.Raised
177+ styleColor: "black"
178+ }
179+ }
180+ }
181+
182+ Label {
183+ anchors { left: parent.left; right: parent.right }
184+ text: modelData[3]
185+ fontSize: "medium"
186+ color: Theme.palette.selected.backgroundText
187+ opacity: .6
188+ wrapMode: Text.WordWrap
189+ style: Text.Raised
190+ styleColor: "black"
191+ }
192+ }
193+ }
194+}
Dash/ScopeDelegateMapper.qmlnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+QtObject {
20+ property var scopeDelegateMapping: {"applications.scope": "DashApps.qml",
21+ "home.scope": "DashHome.qml"
22+ }
23+ property string genericScope: "GenericScopeView.qml"
24+
25+ function map(scopeId) {
26+ var customScope = scopeDelegateMapping[scopeId]
27+ if (customScope != undefined) {
28+ return customScope
29+ }
30+ return genericScope
31+ }
32+}
tests/mocks/Ubuntu/SystemSettings/Update/MockSystemImage.qml → Dash/ScopeListView.qmlrenamed+9−11
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2019 The UBports Foundation
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,17 +14,15 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−pragma Singleton
18import QtQuick 2.0
17import QtQuick 2.0
18+import ListViewWithPageHeader 0.1
19
19
20−Item {
20+ListViewWithPageHeader {
21− id: root
21+ maximumFlickVelocity: height * 10
22+ flickDeceleration: height * 2
22
23
23− property int targetBuildNumber: 0
24+ Connections {
24− property bool checkingForUpdates: false
25+ target: greeter
25− property bool updateAvailable: false
26+ onShownChanged: if (greeter.shown) showHeader()
26−
27+ }
27− signal updateDownloaded()
28− signal applyUpdate()
29− signal checkForUpdate()
30}
28}
Dash/ScopeView.qmlnew file+65
@@ -0,0 +1,65 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Utils 0.1
19+import Unity 0.1
20+
21+FocusScope {
22+ property Scope scope
23+ property SortFilterProxyModel categories: categoryFilter
24+ property bool isCurrent
25+ property ListModel searchHistory
26+ property bool moving: false
27+
28+ signal endReached
29+ signal movementStarted
30+ signal positionedAtBeginning
31+
32+ // FIXME delay the search so that daemons have time to settle, note that
33+ // removing this will break ScopeView::test_changeScope
34+ onScopeChanged: {
35+ if (scope) {
36+ timer.restart();
37+ scope.activateApplication.connect(activateApp);
38+ }
39+ }
40+
41+ function activateApp(desktopFilePath) {
42+ shell.activateApplication(desktopFilePath);
43+ }
44+
45+ Binding {
46+ target: scope
47+ property: "isActive"
48+ value: isCurrent
49+ }
50+
51+ Timer {
52+ id: timer
53+ interval: 2000
54+ onTriggered: scope.searchQuery = ""
55+ }
56+
57+ SortFilterProxyModel {
58+ id: categoryFilter
59+ model: scope ? scope.categories : null
60+ dynamicSortFilter: true
61+ filterRole: Categories.RoleCount
62+ filterRegExp: /^0$/
63+ invertMatch: true
64+ }
65+}
Dash/SearchableResultModel.qmlnew file+44
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import Utils 0.1
18+import Unity 0.1
19+
20+SortFilterProxyModel {
21+ id: root
22+
23+ property string searchQuery: ""
24+ property bool hideOnSearch: false
25+
26+ filterRole: CategoryResults.RoleTitle
27+
28+ function get(index) {
29+ return model.get(mapToSource(index))
30+ }
31+
32+ onSearchQueryChanged: {
33+ if (searchQuery.length == 0) {
34+ filterRegExp = RegExp("");
35+ filterCaseSensitivity = Qt.CaseInsensitive;
36+ } else if (!hideOnSearch) {
37+ setFilterWildcard(searchQuery);
38+ filterCaseSensitivity = Qt.CaseInsensitive;
39+ } else {
40+ filterRegExp = /^$/;
41+ filterCaseSensitivity = Qt.CaseInsensitive;
42+ }
43+ }
44+}
qml/Stage/ResizeGrip.qml → Dash/Video/CarouselDelegateVideo.qmlrenamed+21−25
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,33 +14,29 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19+import "../../Components"
19
20
20−Rectangle {
21+BaseCarouselDelegate {
21− width: units.gu(4)
22+ id: item
22− height: width
23− radius: height / 2
24− color: theme.palette.normal.background
25− opacity: 0.95
26
23
27− // to be set from outside
24+ UbuntuShape {
28− property Item resizeTarget
29−
30− Image {
31− source: "graphics/arrows.png"
32− anchors.centerIn: parent
33− width: units.gu(2)
34− height: width
35− fillMode: Image.PreserveAspectFit
36− }
37−
38− MouseArea {
39 anchors.fill: parent
25 anchors.fill: parent
40− anchors.margins: -units.gu(1.5)
26+ radius: "medium"
41− hoverEnabled: true
27+ borderSource: ""
28+ image: Image {
29+ asynchronous: true
30+ sourceSize { width: item.width; height: item.height }
31+ source: model ? model.icon : ""
32+ }
33+ }
42
34
43− Mouse.enabled: resizeTarget
35+ BorderImage {
44− Mouse.forwardTo: resizeTarget
36+ anchors.centerIn: parent
37+ opacity: 0.6
38+ source: "../../Components/graphics/non-selected.sci"
39+ width: parent.width + units.gu(1.5)
40+ height: parent.height + units.gu(1.5)
45 }
41 }
46}
42}
Dash/Video/VideoFilterGrid.qmlnew file+52
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+import "../Generic"
20+
21+GenericFilterGrid {
22+ id: filtergrid
23+
24+ delegateWidth: units.gu(11)
25+ delegateHeight: units.gu(15)
26+
27+ iconWidth: units.gu(11)
28+ iconHeight: units.gu(11)
29+
30+ delegate: Tile {
31+ id: tile
32+ objectName: "delegate" + index
33+ width: filtergrid.cellWidth
34+ height: filtergrid.cellHeight
35+ text: model.title
36+ imageWidth: filtergrid.iconWidth
37+ imageHeight: filtergrid.iconHeight
38+ source: model.icon
39+ maximumLineCount: 2
40+ horizontalAlignment: Text.AlignLeft
41+
42+ style: VideoTileStyle {}
43+
44+ onClicked: {
45+ filtergrid.clicked(index, filtergrid.model, tile.y)
46+ }
47+
48+ onPressAndHold: {
49+ filtergrid.pressAndHold(index, filtergrid.model, tile.y)
50+ }
51+ }
52+}
Dash/Video/VideoInfo.qmlnew file+84
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtQuick.XmlListModel 2.0
19+
20+Item {
21+ id: info
22+ property string source
23+
24+ property bool ready: nfo.status == XmlListModel.Ready || nfoTV.status == XmlListModel.Ready
25+ property bool isMovie: true
26+ property variant video: null
27+ property variant tvShow: null
28+
29+ function getActors() {
30+ var c = []
31+ if (video.actor1) c.push(video.actor1)
32+ if (video.actor2) c.push(video.actor2)
33+ if (video.actor3) c.push(video.actor3)
34+ return c
35+ }
36+
37+ onSourceChanged: isMovie = true
38+
39+ XmlListModel {
40+ id: nfo
41+ source: info.source
42+ query: (isMovie) ? "/movie" : "/episodedetails"
43+
44+ XmlRole { name: "title"; query: "title/string()" }
45+ XmlRole { name: "year"; query: "year/number()" }
46+ XmlRole { name: "runtime"; query: "runtime/number()" }
47+ XmlRole { name: "rating"; query: "rating/number()" }
48+ XmlRole { name: "plot"; query: "plot/string()" }
49+ XmlRole { name: "director"; query: "director[1]/string()" }
50+ XmlRole { name: "actor1"; query: "actor[1]/name/string()" }
51+ XmlRole { name: "actor2"; query: "actor[2]/name/string()" }
52+ XmlRole { name: "actor3"; query: "actor[3]/name/string()" }
53+ XmlRole { name: "author"; query: "author[1]/string()" }
54+ XmlRole { name: "season"; query: "season/number()" }
55+ XmlRole { name: "episode"; query: "episode/number()" }
56+
57+ XmlRole { name: "rentPrice"; query: "rent_price/string()" }
58+ XmlRole { name: "buyPrice"; query: "buy_price/string()" }
59+ XmlRole { name: "expires"; query: "expires/string()" }
60+
61+ onStatusChanged: if (status == XmlListModel.Ready) {
62+ if (count > 0) info.video = nfo.get(0)
63+ else info.isMovie = false
64+ } else if (status == XmlListModel.Error) info.isMovie = false
65+ }
66+
67+ XmlListModel {
68+ id: nfoTV
69+ source: (nfo.isMovie) ? "" : info.source.substring(0, info.source.lastIndexOf("/") + 1) + "tvshow.nfo"
70+ query: "/tvshow"
71+
72+ XmlRole { name: "title"; query: "title/string()" }
73+
74+ onStatusChanged: if (status == XmlListModel.Ready) {
75+ if (count > 0) info.tvShow = nfoTV.get(0)
76+ } else if (status == XmlListModel.Error) {
77+ // Search for tvshow.nfo in the directory above this one to cater
78+ // for directory layout Show/Season
79+ var path = info.source.split("/")
80+ path.splice(-2, 2, "tvshow.nfo")
81+ source = path.join("/")
82+ }
83+ }
84+}
Dash/Video/VideoTileStyle.qmlnew file+87
@@ -0,0 +1,87 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: tile
22+
23+ anchors.fill: parent
24+
25+ Image {
26+ id: icon
27+ anchors {
28+ top: parent.top
29+ horizontalCenter: parent.horizontalCenter
30+ }
31+ width: styledItem.imageWidth
32+ height: styledItem.imageHeight
33+ source: "graphics/movie_icon_holder.png"
34+
35+ Image {
36+ id: image
37+ objectName: "image"
38+ anchors {
39+ fill: parent;
40+ topMargin: units.gu(2);
41+ bottomMargin: units.gu(2)
42+ }
43+ sourceSize { width: icon.width; height: icon.height }
44+ asynchronous: true
45+ cache: false
46+ source: styledItem.source
47+ fillMode: styledItem.fillMode
48+ horizontalAlignment: Image.AlignHCenter
49+ verticalAlignment: Image.AlignVCenter
50+ }
51+ }
52+
53+ UbuntuShape {
54+ id: borderPressed
55+ objectName: "borderPressed"
56+
57+ anchors.fill: icon
58+ radius: "medium"
59+ borderSource: "radius_pressed.sci"
60+ opacity: styledItem.pressed ? 1.0 : 0.0
61+ Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutQuint } }
62+ }
63+
64+ Label {
65+ id: label
66+ objectName: "label"
67+ anchors {
68+ baseline: icon.bottom
69+ baselineOffset: units.gu(2)
70+ left: icon.left
71+ right: parent.right
72+ rightMargin: units.gu(1)
73+ leftMargin: units.dp(2)
74+ }
75+
76+ color: Theme.palette.selected.backgroundText
77+ opacity: 0.9
78+ style: Text.Raised
79+ styleColor: "black"
80+ fontSize: "small"
81+ elide: Text.ElideRight
82+ horizontalAlignment: styledItem.horizontalAlignment
83+ text: styledItem.text
84+ wrapMode: Text.Wrap
85+ maximumLineCount: styledItem.maximumLineCount
86+ }
87+}
Dash/Video/VideosCarousel.qmlnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../../Components"
19+
20+Carousel {
21+ id: videosCarousel
22+ tileAspectRatio: 198 / 288
23+ minimumTileWidth: units.gu(13)
24+ itemComponent: carouselDelegateVideo
25+ selectedItemScaleFactor: 1.14
26+ cacheBuffer: 1404 // 18px * 13gu * 6
27+ height: implicitHeight + units.gu(6)
28+
29+ Component {
30+ id: carouselDelegateVideo
31+ CarouselDelegateVideo {
32+ }
33+ }
34+}
Dash/Video/graphics/icon_button_amazon@20.pngnew file

Binary file not shown.

Dash/Video/graphics/icon_button_u1@20.pngnew file

Binary file not shown.

Dash/Video/graphics/movie_icon_holder@27.pngnew file

Binary file not shown.

Dash/graphics/header_handlearrow2@20.pngnew file

Binary file not shown.

Dash/graphics/header_handlearrow@20.pngnew file

Binary file not shown.

Dash/graphics/icon_clear@20.pngnew file

Binary file not shown.

Dash/graphics/icon_listview_clear@20.pngnew file

Binary file not shown.

Dash/graphics/icon_search_active@20.pngnew file

Binary file not shown.

Dash/graphics/icon_search_inactive@20.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/angrybirds@12.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/browser@12.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/camera@12.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/facebook@12.pngnew file

Binary file not shown.

tests/graphics/screenshots/gallery@12.png → Dash/graphics/phone/screenshots/gallery@12.pngrenamed

Binary file not shown.

Dash/graphics/phone/screenshots/map@12.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/music@12.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/phone@12.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/settings@12.pngnew file

Binary file not shown.

Dash/graphics/phone/screenshots/twitter@12.pngnew file

Binary file not shown.

Dash/graphics/play_button@18.pngnew file

Binary file not shown.

Dash/graphics/play_button_active@18.pngnew file

Binary file not shown.

Dash/graphics/play_button_active_big@20.pngnew file

Binary file not shown.

Dash/graphics/play_button_big@20.pngnew file

Binary file not shown.

Dash/graphics/tablet/icon_close_preview@20.pngnew file

Binary file not shown.

Dash/graphics/tooltip_arrow@27.pngnew file

Binary file not shown.

qml/Greeter/Clock.qml → Greeter/Clock.qmlrenamed+19−25
@@ -14,9 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19−import "../Panel/Indicators"
20import Unity.Indicators 0.1 as Indicators
19import Unity.Indicators 0.1 as Indicators
21
20
22Item {
21Item {
@@ -25,40 +24,33 @@ Item {
25 implicitWidth: childrenRect.width
24 implicitWidth: childrenRect.width
26 implicitHeight: childrenRect.height
25 implicitHeight: childrenRect.height
27
26
28− // Allows to set the current Date. Will be overwritten if visible
27+ // Allows to set the current Date. Will be overwritten if active
29 property date currentDate
28 property date currentDate
30
29
30+ // If active, time will be updated through the indicators service
31+ property bool active: clock.enabled && clock.visible
32+
31 Component.onCompleted: {
33 Component.onCompleted: {
32− if (visible) {
34+ if (active) {
33 currentDate = new Date()
35 currentDate = new Date()
34 }
36 }
35 }
37 }
36
38
37− Connections {
39+ Indicators.CachedUnityMenuModel {
38− target: i18n
39− onLanguageChanged: {
40− if (visible) {
41− timeLabel.text = Qt.formatTime(clock.currentDate); // kicks time
42− clock.currentDate = new Date(); // kicks date
43− }
44− }
45− }
46−
47− Indicators.SharedUnityMenuModel {
48 id: timeModel
40 id: timeModel
49 objectName: "timeModel"
41 objectName: "timeModel"
50
42
51 busName: "com.canonical.indicator.datetime"
43 busName: "com.canonical.indicator.datetime"
52− actions: { "indicator": "/com/canonical/indicator/datetime" }
44+ actionsObjectPath: "/com/canonical/indicator/datetime"
53− menuObjectPath: clock.visible ? "/com/canonical/indicator/datetime/phone" : ""
45+ menuObjectPath: clock.active ? "/com/canonical/indicator/datetime/phone" : ""
54− }
55
46
56− Indicators.ModelActionRootState {
47+ Indicators.RootActionState {
57− menu: timeModel.model
48+ menu: timeModel.model
58− onUpdated: {
49+ onUpdated: {
59− if (timeLabel.text != rightLabel) {
50+ if (timeLabel.text != rightLabel) {
60− if (rightLabel != "") timeLabel.text = rightLabel;
51+ timeLabel.text = rightLabel;
61− clock.currentDate = new Date();
52+ clock.currentDate = new Date();
53+ }
62 }
54 }
63 }
55 }
64 }
56 }
@@ -73,6 +65,7 @@ Item {
73 anchors.horizontalCenter: parent.horizontalCenter
65 anchors.horizontalCenter: parent.horizontalCenter
74 font.pixelSize: units.gu(7.5)
66 font.pixelSize: units.gu(7.5)
75 color: "white"
67 color: "white"
68+ opacity: 0.5
76 text: Qt.formatTime(clock.currentDate)
69 text: Qt.formatTime(clock.currentDate)
77 font.weight: Font.Light
70 font.weight: Font.Light
78 }
71 }
@@ -84,6 +77,7 @@ Item {
84 anchors.horizontalCenter: parent.horizontalCenter
77 anchors.horizontalCenter: parent.horizontalCenter
85 fontSize: "medium"
78 fontSize: "medium"
86 color: "white"
79 color: "white"
80+ opacity: 0.5
87 text: Qt.formatDate(clock.currentDate, Qt.DefaultLocaleLongDate)
81 text: Qt.formatDate(clock.currentDate, Qt.DefaultLocaleLongDate)
88 font.weight: Font.Light
82 font.weight: Font.Light
89 }
83 }
qml/Greeter/Dot.qml → Greeter/Dot.qmlrenamed+1−1
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18
18
19Image {
19Image {
20 states: [
20 states: [
qml/Greeter/Gradient.js → Greeter/Gradient.jsrenamed

The content is the same.

Greeter/Greeter.qmlnew file+125
@@ -0,0 +1,125 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Gestures 0.1
20+import LightDM 0.1 as LightDM
21+import "../Components"
22+import "../Components/Math.js" as MathLocal
23+
24+Showable {
25+ id: greeter
26+ enabled: shown
27+ created: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.ready
28+
29+ property url defaultBackground
30+
31+ // 1 when fully shown and 0 when fully hidden
32+ property real showProgress: MathLocal.clamp((width + x) / width, 0, 1)
33+
34+ showAnimation: StandardAnimation { property: "x"; to: 0 }
35+ hideAnimation: StandardAnimation { property: "x"; to: -width }
36+
37+ property alias dragHandleWidth: dragHandle.width
38+ property alias model: greeterContentLoader.model
39+ property bool locked: shown && !LightDM.Greeter.promptless
40+
41+ readonly property bool narrowMode: !multiUser && width <= units.gu(60)
42+ readonly property bool multiUser: LightDM.Users.count > 1
43+
44+ readonly property bool leftTeaserPressed: greeterContentLoader.status == Loader.Ready &&
45+ greeterContentLoader.item.leftTeaserPressed
46+ readonly property bool rightTeaserPressed: greeterContentLoader.status == Loader.Ready &&
47+ greeterContentLoader.item.rightTeaserPressed
48+
49+ readonly property int currentIndex: greeterContentLoader.currentIndex
50+
51+ signal selected(int uid)
52+ signal unlocked(int uid)
53+
54+ onRightTeaserPressedChanged: {
55+ if (rightTeaserPressed && !locked && x == 0) {
56+ teasingTimer.start();
57+ }
58+ }
59+
60+ Loader {
61+ id: greeterContentLoader
62+ objectName: "greeterContentLoader"
63+ anchors.fill: parent
64+ property var model: LightDM.Users
65+ property int currentIndex: 0
66+ property var infographicModel: LightDM.Infographic
67+
68+ source: required ? "GreeterContent.qml" : ""
69+
70+ Connections {
71+ target: greeterContentLoader.item
72+
73+ onSelected: {
74+ greeter.selected(uid);
75+ greeterContentLoader.currentIndex = uid;
76+ }
77+ onUnlocked: greeter.unlocked(uid);
78+ }
79+ }
80+
81+ Timer {
82+ id: teasingTimer
83+ interval: 200
84+ }
85+
86+ states: [
87+ State {
88+ name: "teasing"
89+ when: teasingTimer.running
90+ PropertyChanges {
91+ target: greeter
92+ x: -units.gu(2)
93+ }
94+ }
95+ ]
96+ transitions: [
97+ Transition {
98+ from: "*"
99+ to: "*"
100+ NumberAnimation {
101+ target: greeter
102+ property: "x"
103+ duration: 300
104+ easing.type: Easing.OutCubic
105+ }
106+ }
107+ ]
108+
109+ DragHandle {
110+ id: dragHandle
111+
112+ anchors.top: parent.top
113+ anchors.bottom: parent.bottom
114+ anchors.right: parent.right
115+
116+ // no need for requiring a directional drag since we are covering the screen
117+ // anyway (i.e., no change user could be trying to interact with some other
118+ // UI element)
119+ distanceThreshold: 0
120+
121+ enabled: greeter.narrowMode || !greeter.locked
122+
123+ direction: Direction.Leftwards
124+ }
125+}
Greeter/GreeterContent.qmlnew file+163
@@ -0,0 +1,163 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import AccountsService 0.1
19+import Ubuntu.Components 0.1
20+import LightDM 0.1 as LightDM
21+import "../Components"
22+
23+MouseArea {
24+ id: root
25+ anchors.fill: parent
26+
27+ property bool ready: wallpaper.source == "" || wallpaper.status == Image.Ready || wallpaper.status == Image.Error
28+ property bool leftTeaserPressed: teasingMouseArea.pressed &&
29+ teasingMouseArea.mouseX < teasingMouseArea.width / 2
30+ property bool rightTeaserPressed: teasingMouseArea.pressed &&
31+ teasingMouseArea.mouseX > teasingMouseArea.width / 2
32+
33+ signal selected(int uid)
34+ signal unlocked(int uid)
35+
36+ Rectangle {
37+ // In case wallpaper fails to load
38+ id: wallpaperBackup
39+ anchors.fill: parent
40+ color: "black"
41+ }
42+
43+ property url backgroundValue: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : greeter.defaultBackground
44+ onBackgroundValueChanged: wallpaper.source = backgroundValue
45+
46+ CrossFadeImage {
47+ id: wallpaper
48+ objectName: "wallpaper"
49+ anchors.fill: parent
50+ fillMode: Image.PreserveAspectCrop
51+ }
52+
53+ // See Shell.qml's backgroundSettings treatment for why we need a separate
54+ // Image, but it boils down to avoiding binding loop detection.
55+ Image {
56+ source: wallpaper.source
57+ height: 0
58+ width: 0
59+ sourceSize.height: 0
60+ sourceSize.width: 0
61+ onStatusChanged: {
62+ if (status == Image.Error && source != greeter.defaultBackground) {
63+ wallpaper.source = greeter.defaultBackground
64+ }
65+ }
66+ }
67+
68+ Rectangle {
69+ anchors.fill: parent
70+ color: "black"
71+ opacity: 0.4
72+ }
73+
74+ MouseArea {
75+ id: teasingMouseArea
76+ anchors.fill: parent
77+ }
78+
79+ Loader {
80+ id: loginLoader
81+ objectName: "loginLoader"
82+ anchors {
83+ left: parent.left
84+ leftMargin: Math.min(parent.width * 0.16, units.gu(20))
85+ verticalCenter: parent.verticalCenter
86+ }
87+ width: units.gu(29)
88+ height: parent.height
89+
90+ // TODO: Once we have a system API for determining which mode we are
91+ // in, tablet/phone/desktop, that should be used instead of narrowMode.
92+ source: greeter.narrowMode ? "" : "LoginList.qml"
93+
94+ onLoaded: {
95+ item.currentIndex = greeterContentLoader.currentIndex;
96+ selected(item.currentIndex);
97+ item.resetAuthentication();
98+ }
99+
100+ Binding {
101+ target: loginLoader.item
102+ property: "model"
103+ value: greeterContentLoader.model
104+ }
105+
106+ Connections {
107+ target: loginLoader.item
108+
109+ onSelected: {
110+ root.selected(uid);
111+ }
112+
113+ onUnlocked: {
114+ root.unlocked(uid);
115+ }
116+
117+ onCurrentIndexChanged: {
118+ if (greeterContentLoader.currentIndex !== loginLoader.item.currentIndex) {
119+ greeterContentLoader.currentIndex = loginLoader.item.currentIndex;
120+ }
121+ }
122+ }
123+ }
124+
125+ Infographics {
126+ id: infographics
127+ objectName: "infographics"
128+ height: narrowMode ? parent.height : 0.75 * parent.height
129+ model: greeterContentLoader.infographicModel
130+
131+ property string selectedUser
132+ property string infographicUser: AccountsService.statsWelcomeScreen ? selectedUser : ""
133+ onInfographicUserChanged: greeterContentLoader.infographicModel.username = infographicUser
134+
135+ Component.onCompleted: {
136+ selectedUser = greeterContentLoader.model.data(greeterContentLoader.currentIndex, LightDM.UserRoles.NameRole)
137+ greeterContentLoader.infographicModel.username = infographicUser
138+ greeterContentLoader.infographicModel.readyForDataChange()
139+ }
140+
141+ Connections {
142+ target: root
143+ onSelected: infographics.selectedUser = greeterContentLoader.model.data(uid, LightDM.UserRoles.NameRole)
144+ }
145+
146+ anchors {
147+ verticalCenter: parent.verticalCenter
148+ left: narrowMode ? root.left : loginLoader.right
149+ right: root.right
150+ }
151+ }
152+
153+ Clock {
154+ id: clock
155+ visible: narrowMode
156+
157+ anchors {
158+ top: parent.top
159+ topMargin: units.gu(2)
160+ horizontalCenter: parent.horizontalCenter
161+ }
162+ }
163+}
qml/Greeter/Infographics.qml → Greeter/Infographics.qmlrenamed+134−108
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013-2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,10 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17+import "../Components"
17import "Gradient.js" as Gradient
18import "Gradient.js" as Gradient
18−import QtQuick 2.4
19+import QtQuick 2.0
19−import Ubuntu.Components 1.3
20+import Ubuntu.Components 0.1
20
21
21Item {
22Item {
22 id: infographic
23 id: infographic
@@ -25,28 +26,8 @@ Item {
25
26
26 property int animDuration: 10
27 property int animDuration: 10
27
28
28− property int currentWeekDay
29−
30− QtObject {
31− id: d
32− objectName: "infographicPrivate"
33− property bool useDotAnimation: true
34− property int circleModifier: useDotAnimation ? 1 : 2
35− property bool animating: dotHideAnimTimer.running
36− || dotShowAnimTimer.running
37− || circleChangeAnimTimer.running
38− }
39−
40− QtObject {
41− id: whiteTheme
42− property color main: "white"
43− property color start: "white"
44− property color end: "white"
45− }
46−
47 Connections {
29 Connections {
48 target: model
30 target: model
49− ignoreUnknownSignals: model === undefined
50
31
51 onDataAboutToAppear: startHideAnimation() // hide "no data" label
32 onDataAboutToAppear: startHideAnimation() // hide "no data" label
52 onDataAppeared: startShowAnimation()
33 onDataAppeared: startShowAnimation()
@@ -58,53 +39,27 @@ Item {
58 onDataDisappeared: startShowAnimation() // show "no data" label
39 onDataDisappeared: startShowAnimation() // show "no data" label
59 }
40 }
60
41
61− LiveTimer {
62− frequency: LiveTimer.Hour
63− onTrigger: handleTimerTrigger()
64− }
65−
66− function handleTimerTrigger(){
67− var today = new Date().getDay()
68− if(infographic.currentWeekDay !== today){
69− infographic.currentWeekDay = today
70− reloadUserData();
71− }
72− }
73−
74− function reloadUserData(){
75− d.useDotAnimation = false
76− infographic.model.nextDataSource()
77− }
78−
79 function startShowAnimation() {
42 function startShowAnimation() {
80 dotHideAnimTimer.stop()
43 dotHideAnimTimer.stop()
44+ circleShrinkAnimTimer.stop()
81 notification.hideAnim.stop()
45 notification.hideAnim.stop()
82
46
83− if (d.useDotAnimation) {
84− dotShowAnimTimer.startFromBeginning()
47+ dotShowAnimTimer.startFromBeginning()
85− }
86 notification.showAnim.start()
48 notification.showAnim.start()
87 }
49 }
88
50
89 function startHideAnimation() {
51 function startHideAnimation() {
90 dotShowAnimTimer.stop()
52 dotShowAnimTimer.stop()
91− circleChangeAnimTimer.stop()
53+ circleGrowAnimTimer.stop()
92 notification.showAnim.stop()
54 notification.showAnim.stop()
93
55
94− if (d.useDotAnimation) {
95− dotHideAnimTimer.startFromBeginning()
56+ dotHideAnimTimer.startFromBeginning()
96− } else {
97− circleChangeAnimTimer.startFromBeginning()
98− }
99 notification.hideAnim.start()
57 notification.hideAnim.start()
100 }
58 }
101
59
102− visible: model.username !== ""
60+ visible: model.label !== ""
103
61
104− Component.onCompleted: {
62+ Component.onCompleted: startShowAnimation()
105− currentWeekDay = new Date().getDay()
106− startShowAnimation()
107− }
108
63
109 Item {
64 Item {
110 id: dataCircle
65 id: dataCircle
@@ -118,22 +73,22 @@ Item {
118 anchors.centerIn: parent
73 anchors.centerIn: parent
119
74
120 Timer {
75 Timer {
121− id: circleChangeAnimTimer
76+ id: circleGrowAnimTimer
122
77
123 property int pastCircleCounter
78 property int pastCircleCounter
124 property int presentCircleCounter
79 property int presentCircleCounter
125
80
126− interval: notification.duration
81+ interval: animDuration
127 running: false
82 running: false
128 repeat: true
83 repeat: true
129 onTriggered: {
84 onTriggered: {
130 if (pastCircleCounter < pastCircles.count) {
85 if (pastCircleCounter < pastCircles.count) {
131 var nextCircle = pastCircles.itemAt(pastCircleCounter++)
86 var nextCircle = pastCircles.itemAt(pastCircleCounter++)
132− if (nextCircle !== null) nextCircle.pastCircleChangeAnim.start()
87+ if (nextCircle !== null) nextCircle.pastCircleGrowAnim.start()
133 }
88 }
134 if (pastCircleCounter > pastCircles.count / 2) {
89 if (pastCircleCounter > pastCircles.count / 2) {
135 var nextCircle = presentCircles.itemAt(presentCircleCounter++)
90 var nextCircle = presentCircles.itemAt(presentCircleCounter++)
136− if (nextCircle !== null) nextCircle.presentCircleChangeAnim.start()
91+ if (nextCircle !== null) nextCircle.presentCircleGrowAnim.start()
137 }
92 }
138 if (presentCircleCounter > infographic.model.currentDay && pastCircleCounter >= pastCircles.count) {
93 if (presentCircleCounter > infographic.model.currentDay && pastCircleCounter >= pastCircles.count) {
139 stop()
94 stop()
@@ -141,8 +96,39 @@ Item {
141 }
96 }
142
97
143 function startFromBeginning() {
98 function startFromBeginning() {
144− circleChangeAnimTimer.pastCircleCounter = 0
99+ circleGrowAnimTimer.pastCircleCounter = 0
145− circleChangeAnimTimer.presentCircleCounter = 0
100+ circleGrowAnimTimer.presentCircleCounter = 0
101+ start()
102+ }
103+ }
104+
105+ Timer {
106+ id: circleShrinkAnimTimer
107+
108+ property int pastCircleCounter
109+ property int presentCircleCounter
110+
111+ interval: animDuration
112+ running: false
113+ repeat: true
114+ onTriggered: {
115+ if (pastCircleCounter >= 0) {
116+ var nextCircle = pastCircles.itemAt(pastCircleCounter--)
117+ if (nextCircle !== null) nextCircle.pastCircleShrinkAnim.start()
118+ }
119+ if (pastCircleCounter < pastCircles.count / 2) {
120+ var nextCircle = presentCircles.itemAt(presentCircleCounter--)
121+ if (nextCircle !== null) nextCircle.presentCircleShrinkAnim.start()
122+ }
123+ if (presentCircleCounter < 0) {
124+ stop()
125+ infographic.model.readyForDataChange()
126+ }
127+ }
128+
129+ function startFromBeginning() {
130+ pastCircleCounter = pastCircles.count - 1
131+ presentCircleCounter = model.currentDay
146 start()
132 start()
147 }
133 }
148 }
134 }
@@ -153,11 +139,12 @@ Item {
153 model: infographic.model.secondMonth
139 model: infographic.model.secondMonth
154
140
155 delegate: ObjectPositioner {
141 delegate: ObjectPositioner {
156− property alias pastCircleChangeAnim: pastCircleChangeAnim
142+ property alias pastCircleGrowAnim: pastCircleGrowAnim
143+ property alias pastCircleShrinkAnim: pastCircleShrinkAnim
157
144
158 index: model.index
145 index: model.index
159 count: pastCircles.count
146 count: pastCircles.count
160− radius: dataCircle.width / 2
147+ radius: parent.width / 2
161 halfSize: pastCircle.width / 2
148 halfSize: pastCircle.width / 2
162 posOffset: 0.0
149 posOffset: 0.0
163
150
@@ -171,36 +158,54 @@ Item {
171 width: dataCircle.width / divisor
158 width: dataCircle.width / divisor
172 height: dataCircle.height / divisor
159 height: dataCircle.height / divisor
173 opacity: 0.0
160 opacity: 0.0
174− circleScale: 0.0
161+ scale: 0.0
175 visible: modelData !== undefined
162 visible: modelData !== undefined
176− color: "transparent"
163+ color: Gradient.threeColorByIndex(index, count, infographic.model.secondColor)
177− centerCircle: dataCircle
178
164
179 SequentialAnimation {
165 SequentialAnimation {
180− id: pastCircleChangeAnim
166+ id: pastCircleGrowAnim
181
167
182 loops: 1
168 loops: 1
183 ParallelAnimation {
169 ParallelAnimation {
184 PropertyAnimation {
170 PropertyAnimation {
185 target: pastCircle
171 target: pastCircle
186 property: "opacity"
172 property: "opacity"
173+ from: 0.0
187 to: pastCircle.circleOpacity
174 to: pastCircle.circleOpacity
188 easing.type: Easing.OutCurve
175 easing.type: Easing.OutCurve
189− duration: circleChangeAnimTimer.interval * d.circleModifier
176+ duration: circleGrowAnimTimer.interval * 4
190 }
177 }
191 PropertyAnimation {
178 PropertyAnimation {
192 target: pastCircle
179 target: pastCircle
193− property: "circleScale"
180+ property: "scale"
181+ from: 0.0
194 to: modelData
182 to: modelData
195 easing.type: Easing.OutCurve
183 easing.type: Easing.OutCurve
196− duration: circleChangeAnimTimer.interval * d.circleModifier
184+ duration: circleGrowAnimTimer.interval * 4
197 }
185 }
198− ColorAnimation {
186+ }
187+ }
188+
189+ SequentialAnimation {
190+ id: pastCircleShrinkAnim
191+
192+ loops: 1
193+ ParallelAnimation {
194+ PropertyAnimation {
195+ target: pastCircle
196+ property: "opacity"
197+ from: pastCircle.circleOpacity
198+ to: 0.0
199+ easing.type: Easing.OutCurve
200+ duration: circleShrinkAnimTimer.interval * 4
201+ }
202+ PropertyAnimation {
199 target: pastCircle
203 target: pastCircle
200− property: "color"
204+ property: "scale"
201− to: Gradient.threeColorByIndex(index, count, whiteTheme)
205+ from: modelData
206+ to: 0.0
202 easing.type: Easing.OutCurve
207 easing.type: Easing.OutCurve
203− duration: circleChangeAnimTimer.interval * d.circleModifier
208+ duration: circleShrinkAnimTimer.interval * 4
204 }
209 }
205 }
210 }
206 }
211 }
@@ -214,11 +219,12 @@ Item {
214 model: infographic.model.firstMonth
219 model: infographic.model.firstMonth
215
220
216 delegate: ObjectPositioner {
221 delegate: ObjectPositioner {
217− property alias presentCircleChangeAnim: presentCircleChangeAnim
222+ property alias presentCircleGrowAnim: presentCircleGrowAnim
223+ property alias presentCircleShrinkAnim: presentCircleShrinkAnim
218
224
219 index: model.index
225 index: model.index
220 count: presentCircles.count
226 count: presentCircles.count
221− radius: dataCircle.width / 2
227+ radius: parent.width / 2
222 halfSize: presentCircle.width / 2
228 halfSize: presentCircle.width / 2
223 posOffset: 0.0
229 posOffset: 0.0
224
230
@@ -232,13 +238,12 @@ Item {
232 width: dataCircle.width / divisor
238 width: dataCircle.width / divisor
233 height: dataCircle.height / divisor
239 height: dataCircle.height / divisor
234 opacity: 0.0
240 opacity: 0.0
235− circleScale: 0.0
241+ scale: 0.0
236 visible: modelData !== undefined
242 visible: modelData !== undefined
237− color: "transparent"
243+ color: Gradient.threeColorByIndex(index, infographic.model.currentDay, infographic.model.firstColor)
238− centerCircle: dataCircle
239
244
240 SequentialAnimation {
245 SequentialAnimation {
241− id: presentCircleChangeAnim
246+ id: presentCircleGrowAnim
242
247
243 loops: 1
248 loops: 1
244
249
@@ -248,21 +253,36 @@ Item {
248 property: "opacity"
253 property: "opacity"
249 to: presentCircle.circleOpacity
254 to: presentCircle.circleOpacity
250 easing.type: Easing.OutCurve
255 easing.type: Easing.OutCurve
251− duration: circleChangeAnimTimer.interval * d.circleModifier
256+ duration: circleGrowAnimTimer.interval * 4
252 }
257 }
253 PropertyAnimation {
258 PropertyAnimation {
254 target: presentCircle
259 target: presentCircle
255− property: "circleScale"
260+ property: "scale"
256 to: modelData
261 to: modelData
257 easing.type: Easing.OutCurve
262 easing.type: Easing.OutCurve
258− duration: circleChangeAnimTimer.interval * d.circleModifier
263+ duration: circleGrowAnimTimer.interval * 4
259 }
264 }
260− ColorAnimation {
265+ }
266+ }
267+
268+ SequentialAnimation {
269+ id: presentCircleShrinkAnim
270+
271+ loops: 1
272+ ParallelAnimation {
273+ PropertyAnimation {
261 target: presentCircle
274 target: presentCircle
262− property: "color"
275+ property: "opacity"
263− to: Gradient.threeColorByIndex(index, infographic.model.currentDay, whiteTheme)
276+ to: 0.0
264 easing.type: Easing.OutCurve
277 easing.type: Easing.OutCurve
265− duration: circleChangeAnimTimer.interval * d.circleModifier
278+ duration: circleShrinkAnimTimer.interval * 4
279+ }
280+ PropertyAnimation {
281+ target: presentCircle
282+ property: "scale"
283+ to: 0.0
284+ easing.type: Easing.OutCurve
285+ duration: circleShrinkAnimTimer.interval * 4
266 }
286 }
267 }
287 }
268 }
288 }
@@ -270,6 +290,15 @@ Item {
270 }
290 }
271 }
291 }
272
292
293+ Image {
294+ id: backgroundCircle
295+ objectName: "backgroundCircle"
296+
297+ anchors.fill: parent
298+
299+ source: "graphics/infographic_circle_back.png"
300+ }
301+
273 Timer {
302 Timer {
274 id: dotShowAnimTimer
303 id: dotShowAnimTimer
275
304
@@ -278,16 +307,14 @@ Item {
278 interval: animDuration * 0.5; running: false; repeat: true
307 interval: animDuration * 0.5; running: false; repeat: true
279 onTriggered: {
308 onTriggered: {
280 if (dotCounter < dots.count) {
309 if (dotCounter < dots.count) {
281− var nextDot = dots.itemAt(dotCounter);
310+ var nextDot = dots.itemAt(dotCounter++)
282− if (nextDot) {
283− nextDot.unlockAnimation.start();
311+ nextDot.unlockAnimation.start()
284− if (++dotCounter == Math.round(dots.count / 2)) {
285− circleChangeAnimTimer.startFromBeginning();
286− }
287− }
288 } else {
312 } else {
289 stop()
313 stop()
290 }
314 }
315+ if (dotCounter == Math.round(dots.count / 2)) {
316+ circleGrowAnimTimer.startFromBeginning()
317+ }
291 }
318 }
292
319
293 function startFromBeginning() {
320 function startFromBeginning() {
@@ -313,8 +340,8 @@ Item {
313 } else {
340 } else {
314 stop()
341 stop()
315 }
342 }
316− if (dotCounter == 0) {
343+ if (dotCounter == Math.round(dots.count / 2)) {
317− infographic.model.readyForDataChange()
344+ circleShrinkAnimTimer.startFromBeginning()
318 }
345 }
319 }
346 }
320
347
@@ -340,7 +367,7 @@ Item {
340
367
341 index: model.index
368 index: model.index
342 count: dots.count
369 count: dots.count
343− radius: dataCircle.width / 2
370+ radius: backgroundCircle.width / 2
344 halfSize: dot.width / 2
371 halfSize: dot.width / 2
345 posOffset: radius / dot.width / 3
372 posOffset: radius / dot.width / 3
346 state: dot.state
373 state: dot.state
@@ -349,7 +376,7 @@ Item {
349 id: dot
376 id: dot
350 objectName: "dot" + index
377 objectName: "dot" + index
351
378
352− property real baseOpacity: 1
379+ property real baseOpacity: 0.4
353
380
354 width: units.dp(5) * parent.radius / 200
381 width: units.dp(5) * parent.radius / 200
355 height: units.dp(5) * parent.radius / 200
382 height: units.dp(5) * parent.radius / 200
@@ -385,10 +412,9 @@ Item {
385 property alias hideAnim: decreaseOpacity
412 property alias hideAnim: decreaseOpacity
386 property alias showAnim: increaseOpacity
413 property alias showAnim: increaseOpacity
387
414
388− property real baseOpacity: 1
415+ property real baseOpacity: 0.6
389− property real duration: dotShowAnimTimer.interval * 5
390
416
391− height: 0.7 * dataCircle.width
417+ height: 0.7 * backgroundCircle.width
392 width: notification.height
418 width: notification.height
393 anchors.centerIn: parent
419 anchors.centerIn: parent
394
420
@@ -406,7 +432,7 @@ Item {
406 property: "opacity"
432 property: "opacity"
407 from: 0.0
433 from: 0.0
408 to: notification.baseOpacity
434 to: notification.baseOpacity
409− duration: notification.duration * dots.count
435+ duration: dotShowAnimTimer.interval * dots.count * 5
410 }
436 }
411
437
412 PropertyAnimation {
438 PropertyAnimation {
@@ -416,20 +442,20 @@ Item {
416 property: "opacity"
442 property: "opacity"
417 from: notification.baseOpacity
443 from: notification.baseOpacity
418 to: 0.0
444 to: 0.0
419− duration: notification.duration * dots.count
445+ duration: dotShowAnimTimer.interval * dots.count * 5
420− onStopped: if (!d.useDotAnimation) infographic.model.readyForDataChange()
421 }
446 }
422 }
447 }
423 }
448 }
424
449
425 MouseArea {
450 MouseArea {
426 anchors.fill: dataCircle
451 anchors.fill: dataCircle
427− enabled: notification.text != ""
428
452
429 onDoubleClicked: {
453 onDoubleClicked: {
430− if (!d.animating) {
454+ if (!dotHideAnimTimer.running &&
431− reloadUserData()
455+ !dotShowAnimTimer.running &&
432− }
456+ !circleShrinkAnimTimer.running &&
457+ !circleGrowAnimTimer.running)
458+ infographic.model.nextDataSource()
433 }
459 }
434 }
460 }
435}
461}
Greeter/Lockscreen.qmlnew file+164
@@ -0,0 +1,164 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+import LightDM 0.1 as LightDM
21+
22+Showable {
23+ id: root
24+
25+ // Determine if a numeric or alphanumeric pad is used.
26+ property bool alphaNumeric: false
27+
28+ // Placeholder text
29+ property string placeholderText: ""
30+
31+ // In case the Lockscreen can show a greeter message, this is the username
32+ property string username: ""
33+
34+ // As the numeric PIN pad doesn't have a OK button by design, we need to auto-confirm on a certain length.
35+ // This is ignored by the alphaNumeric lockscreen as that one is confirmed with pressing enter on the OSK.
36+ property int pinLength: 4
37+
38+ property url background: ""
39+
40+ signal unlocked()
41+ signal cancel()
42+ signal emergencyCall()
43+
44+ onRequiredChanged: {
45+ if (required && pinPadLoader.item) {
46+ pinPadLoader.item.clear(false);
47+ }
48+ }
49+
50+ function reset() {
51+ // This causes the loader below to destry and recreate the source
52+ pinPadLoader.resetting = true;
53+ pinPadLoader.resetting = false;
54+ }
55+
56+ Rectangle {
57+ // In case wallpaper fails to load or is undefined
58+ id: wallpaperBackup
59+ anchors.fill: parent
60+ color: "black"
61+ }
62+
63+ Image {
64+ id: wallpaper
65+ anchors.fill: parent
66+ source: root.required ? root.background : ""
67+ fillMode: Image.PreserveAspectCrop
68+ }
69+
70+ MouseArea {
71+ anchors.fill: root
72+ }
73+
74+ Loader {
75+ id: pinPadLoader
76+ objectName: "pinPadLoader"
77+ anchors {
78+ left: parent.left
79+ right: parent.right
80+ verticalCenter: parent.verticalCenter
81+ verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : -units.gu(4)
82+ }
83+ property bool resetting: false
84+
85+ source: (!resetting && root.required) ? (root.alphaNumeric ? "PassphraseLockscreen.qml" : "PinLockscreen.qml") : ""
86+
87+ Connections {
88+ target: pinPadLoader.item
89+
90+ onEntered: {
91+ LightDM.Greeter.respond(passphrase);
92+ }
93+
94+ onCancel: {
95+ root.cancel()
96+ }
97+ }
98+
99+ Binding {
100+ target: pinPadLoader.item
101+ property: "pinLength"
102+ value: root.pinLength
103+ }
104+ Binding {
105+ target: pinPadLoader.item
106+ property: "placeholderText"
107+ value: root.placeholderText
108+ }
109+ Binding {
110+ target: pinPadLoader.item
111+ property: "username"
112+ value: root.username
113+ }
114+ }
115+
116+ Column {
117+ anchors {
118+ left: parent.left
119+ bottom: parent.bottom
120+ bottomMargin: units.gu(4)
121+ right: parent.right
122+ }
123+ height: childrenRect.height
124+ spacing: units.gu(1)
125+
126+ Icon {
127+ objectName: "emergencyCallIcon"
128+ height: units.gu(3)
129+ width: height
130+ anchors.horizontalCenter: parent.horizontalCenter
131+ name: "phone-app-call-symbolic"
132+ color: "#f3f3e7"
133+ opacity: 0.6
134+
135+ MouseArea {
136+ anchors.fill: parent
137+ onClicked: root.emergencyCall()
138+ }
139+ }
140+
141+ Label {
142+ text: i18n.tr("Emergency Call")
143+ color: "#f3f3e7"
144+ opacity: 0.6
145+ fontSize: "medium"
146+ anchors.horizontalCenter: parent.horizontalCenter
147+ }
148+ }
149+
150+ Connections {
151+ target: LightDM.Greeter
152+
153+ onAuthenticationComplete: {
154+ if (LightDM.Greeter.promptless) {
155+ return;
156+ }
157+ if (LightDM.Greeter.authenticated) {
158+ root.unlocked();
159+ } else {
160+ pinPadLoader.item.clear(true);
161+ }
162+ }
163+ }
164+}
Greeter/LoginList.qmlnew file+293
@@ -0,0 +1,293 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import LightDM 0.1 as LightDM
20+import "../Components"
21+
22+Item {
23+ id: root
24+
25+ property alias userList: userList
26+ property alias model: userList.model
27+ property alias currentIndex: userList.currentIndex
28+
29+ readonly property int numAboveBelow: 4
30+ readonly property int cellHeight: units.gu(5)
31+ readonly property int highlightedHeight: units.gu(10)
32+ readonly property int moveDuration: 200
33+ property bool wasPrompted: false
34+
35+ signal selected(int uid)
36+ signal unlocked(int uid)
37+
38+ Keys.onEscapePressed: root.resetAuthentication()
39+
40+ Rectangle {
41+ id: highlightItem
42+ anchors {
43+ left: parent.left
44+ right: parent.right
45+ verticalCenter: parent.verticalCenter
46+ }
47+ height: root.highlightedHeight
48+ color: Qt.rgba(0.1, 0.1, 0.1, 0.4)
49+ border.color: Qt.rgba(0.4, 0.4, 0.4, 0.4)
50+ border.width: units.dp(1)
51+ radius: units.gu(1.5)
52+ antialiasing: true
53+ }
54+
55+ ListView {
56+ id: userList
57+ objectName: "userList"
58+
59+ anchors.fill: parent
60+
61+ preferredHighlightBegin: userList.height / 2 - root.highlightedHeight / 2
62+ preferredHighlightEnd: userList.height / 2 - root.highlightedHeight / 2
63+ highlightRangeMode: ListView.StrictlyEnforceRange
64+ highlightMoveDuration: root.moveDuration
65+ flickDeceleration: 10000
66+
67+ readonly property bool movingInternally: moveTimer.running || userList.moving
68+
69+ onCurrentIndexChanged: {
70+ if (LightDM.Greeter.authenticationUser != userList.model.data(currentIndex, LightDM.UserRoles.NameRole)) {
71+ root.resetAuthentication();
72+ }
73+ }
74+
75+ onMovingInternallyChanged: {
76+ // Only emit the selected signal once we stop moving to avoid frequent background changes
77+ if (!movingInternally) {
78+ root.selected(userList.currentIndex);
79+ }
80+ }
81+
82+ delegate: Item {
83+ width: parent.width
84+ height: root.cellHeight
85+
86+ readonly property bool belowHighlight: (userList.currentIndex < 0 && index > 0) || (userList.currentIndex >= 0 && index > userList.currentIndex)
87+ readonly property int belowOffset: root.highlightedHeight - root.cellHeight
88+
89+ opacity: {
90+ // The goal here is to make names less and less opaque as they
91+ // leave the highlight area. Can't simply use index, because
92+ // that can change quickly if the user clicks at edges of
93+ // list. So we use actual pixel distance.
94+ var highlightDist = 0;
95+ var realY = y - userList.contentY;
96+ if (belowHighlight)
97+ realY += belowOffset;
98+ if (realY + height <= highlightItem.y)
99+ highlightDist = realY + height - highlightItem.y;
100+ else if (realY >= highlightItem.y + root.highlightedHeight)
101+ highlightDist = realY - highlightItem.y - root.highlightedHeight;
102+ else
103+ return 1;
104+ return 1 - Math.min(1, (Math.abs(highlightDist) + root.cellHeight) / ((root.numAboveBelow + 1) * root.cellHeight))
105+ }
106+
107+ Label {
108+ objectName: "username" + index
109+
110+ anchors {
111+ left: parent.left
112+ leftMargin: units.gu(2)
113+ right: parent.right
114+ rightMargin: units.gu(2)
115+ top: parent.top
116+ // Add an offset to topMargin for any items below the highlight
117+ topMargin: units.gu(1) + (parent.belowHighlight ? parent.belowOffset : 0)
118+ }
119+ text: realName
120+ color: "white"
121+ elide: Text.ElideRight
122+
123+ Behavior on anchors.topMargin { NumberAnimation { duration: root.moveDuration; easing.type: Easing.InOutQuad; } }
124+ }
125+
126+ MouseArea {
127+ anchors {
128+ left: parent.left
129+ right: parent.right
130+ top: parent.top
131+ // Add an offset to topMargin for any items below the highlight
132+ topMargin: parent.belowHighlight ? parent.belowOffset : 0
133+ }
134+ height: parent.height
135+ enabled: userList.currentIndex !== index
136+ onClicked: {
137+ moveTimer.start();
138+ userList.currentIndex = index;
139+ }
140+
141+ Behavior on anchors.topMargin { NumberAnimation { duration: root.moveDuration; easing.type: Easing.InOutQuad; } }
142+ }
143+ }
144+
145+ // This is needed because ListView.moving is not true if the ListView
146+ // moves because of an internal event (e.g. currentIndex has changed)
147+ Timer {
148+ id: moveTimer
149+ running: false
150+ repeat: false
151+ interval: root.moveDuration
152+ }
153+ }
154+
155+ Label {
156+ id: infoLabel
157+ objectName: "infoLabel"
158+ anchors {
159+ bottom: passwordInput.top
160+ left: parent.left
161+ topMargin: units.gu(1)
162+ bottomMargin: units.gu(1)
163+ leftMargin: units.gu(2)
164+ rightMargin: units.gu(1)
165+ }
166+
167+ color: "white"
168+ width: root.width - anchors.leftMargin - anchors.rightMargin
169+ fontSize: "small"
170+ textFormat: Text.StyledText
171+ clip: true
172+
173+ opacity: (userList.movingInternally || text == "") ? 0 : 1
174+ Behavior on opacity {
175+ NumberAnimation { duration: 100 }
176+ }
177+ }
178+
179+ TextField {
180+ id: passwordInput
181+ objectName: "passwordInput"
182+ anchors {
183+ bottom: highlightItem.bottom
184+ horizontalCenter: parent.horizontalCenter
185+ margins: units.gu(1)
186+ }
187+ height: units.gu(4.5)
188+ width: parent.width - anchors.margins * 2
189+ opacity: userList.movingInternally ? 0 : 1
190+
191+ Behavior on opacity {
192+ NumberAnimation { duration: 100 }
193+ }
194+
195+ onAccepted: {
196+ if (!enabled)
197+ return;
198+ root.focus = true; // so that it can handle Escape presses for us
199+ enabled = false;
200+ LightDM.Greeter.respond(text);
201+ }
202+ Keys.onEscapePressed: root.resetAuthentication()
203+
204+ Image {
205+ anchors {
206+ right: parent.right
207+ rightMargin: units.gu(2)
208+ verticalCenter: parent.verticalCenter
209+ }
210+ visible: LightDM.Greeter.promptless
211+ source: "graphics/icon_arrow.png"
212+ }
213+
214+ WrongPasswordAnimation {
215+ id: wrongPasswordAnimation
216+ target: passwordInput
217+ }
218+
219+ Connections {
220+ target: Qt.inputMethod
221+ onVisibleChanged: {
222+ if (!Qt.inputMethod.visible) {
223+ passwordInput.focus = false;
224+ }
225+ }
226+ }
227+
228+ }
229+
230+ MouseArea {
231+ anchors.fill: passwordInput
232+ enabled: LightDM.Greeter.promptless
233+ onClicked: {
234+ if (LightDM.Greeter.authenticated)
235+ root.unlocked(userList.currentIndex);
236+ else
237+ root.resetAuthentication();
238+ }
239+ }
240+
241+ function resetAuthentication() {
242+ if (!userList.currentItem) {
243+ return;
244+ }
245+ infoLabel.text = "";
246+ passwordInput.placeholderText = "";
247+ passwordInput.text = "";
248+ passwordInput.focus = false;
249+ passwordInput.enabled = true;
250+ root.wasPrompted = false;
251+ LightDM.Greeter.authenticate(userList.model.data(currentIndex, LightDM.UserRoles.NameRole));
252+ }
253+
254+ Connections {
255+ target: LightDM.Greeter
256+
257+ onShowMessage: {
258+ // inefficient, but we only rarely deal with messages
259+ text = text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "<br>");
260+ if (isError)
261+ text = "<font color=\"#df382c\">" + text + "</font>"
262+ if (infoLabel.text == "")
263+ infoLabel.text = text;
264+ else
265+ infoLabel.text = infoLabel.text + "<br>" + text;
266+ }
267+
268+ onShowPrompt: {
269+ passwordInput.text = "";
270+ passwordInput.placeholderText = text;
271+ passwordInput.enabled = true;
272+ passwordInput.echoMode = isSecret ? TextInput.Password : TextInput.Normal;
273+ if (root.wasPrompted) // stay in text field if second prompt
274+ passwordInput.focus = true;
275+ root.wasPrompted = true;
276+ }
277+
278+ onAuthenticationComplete: {
279+ if (LightDM.Greeter.promptless) {
280+ passwordInput.placeholderText = LightDM.Greeter.authenticated ? "Tap to unlock" : "Retry";
281+ return;
282+ }
283+ if (LightDM.Greeter.authenticated) {
284+ root.unlocked(userList.currentIndex);
285+ } else {
286+ wrongPasswordAnimation.start();
287+ root.resetAuthentication();
288+ passwordInput.focus = true;
289+ }
290+ passwordInput.text = "";
291+ }
292+ }
293+}
qml/Greeter/ObjectPositioner.qml → Greeter/ObjectPositioner.qmlrenamed+2−2
@@ -14,8 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19
19
20Item {
20Item {
21 property int count
21 property int count
Greeter/PassphraseLockscreen.qmlnew file+87
@@ -0,0 +1,87 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+Item {
22+ id: root
23+ height: highlightItem.height
24+
25+ property alias placeholderText: pinentryField.placeholderText
26+ property string username: ""
27+
28+ signal entered(string passphrase)
29+ signal cancel()
30+
31+ function clear(playAnimation) {
32+ pinentryField.text = "";
33+ if (playAnimation) {
34+ wrongPasswordAnimation.start();
35+ } else {
36+ pinentryField.focus = false
37+ }
38+ }
39+
40+ Rectangle {
41+ id: highlightItem
42+ width: units.gu(32)
43+ height: units.gu(10)
44+ anchors.centerIn: parent
45+ color: Qt.rgba(0.1, 0.1, 0.1, 0.4)
46+ border.color: Qt.rgba(0.4, 0.4, 0.4, 0.4)
47+ border.width: units.dp(1)
48+ radius: units.gu(1.5)
49+ antialiasing: true
50+
51+ Label {
52+ objectName: "greeterLabel"
53+ anchors {
54+ left: parent.left
55+ top: parent.top
56+ right: parent.right
57+ margins: units.gu(1.5)
58+ }
59+ text: root.username.length > 0 ? i18n.tr("Hello %1").arg(root.username) : i18n.tr("Hello")
60+ color: "white"
61+ }
62+
63+ TextField {
64+ id: pinentryField
65+ objectName: "pinentryField"
66+ anchors {
67+ horizontalCenter: parent.horizontalCenter
68+ bottom: parent.bottom
69+ margins: units.gu(1)
70+ }
71+ height: units.gu(4.5)
72+ width: parent.width - units.gu(2)
73+ echoMode: TextInput.Password
74+ opacity: 0.9
75+ hasClearButton: false
76+
77+ onAccepted: {
78+ root.entered(pinentryField.text);
79+ }
80+ }
81+ }
82+
83+ WrongPasswordAnimation {
84+ id: wrongPasswordAnimation
85+ target: pinentryField
86+ }
87+}
Greeter/PinLockscreen.qmlnew file+185
@@ -0,0 +1,185 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1
20+import "../Components"
21+
22+Column {
23+ id: root
24+ anchors.centerIn: parent
25+ spacing: units.gu(3.5)
26+
27+ property alias placeholderText: pinentryField.placeholderText
28+ property int padWidth: units.gu(34)
29+ property int padHeight: units.gu(28)
30+ property int pinLength: 4
31+
32+ signal entered(string passphrase)
33+ signal cancel()
34+
35+ property bool entryEnabled: true
36+
37+ function clear(playAnimation) {
38+ pinentryField.text = "";
39+ if (playAnimation) {
40+ wrongPasswordAnimation.start();
41+ }
42+ }
43+
44+
45+ UbuntuShape {
46+ id: pinentryField
47+ objectName: "pinentryField"
48+ anchors.horizontalCenter: parent.horizontalCenter
49+ color: "#55000000"
50+ width:root.padWidth
51+ height: units.gu(5)
52+ radius: "medium"
53+ property string text: ""
54+ property string placeholderText: ""
55+ onTextChanged: {
56+ pinentryFieldLabel.text = "";
57+ for (var i = 0; i < text.length; ++i) {
58+ pinentryFieldLabel.text += "•";
59+ }
60+ if (text.length === root.pinLength) {
61+ root.entered(text);
62+ }
63+ }
64+
65+ Label {
66+ id: pinentryFieldLabel
67+ anchors.centerIn: parent
68+ font.pixelSize: units.dp(44)
69+ color: "#f3f3e7"
70+ opacity: 0.6
71+ }
72+ Label {
73+ id: pinentryFieldPlaceHolder
74+ anchors.centerIn: parent
75+ color: "grey"
76+ text: parent.placeholderText
77+ visible: pinentryFieldLabel.text.length == 0
78+ }
79+ }
80+
81+ UbuntuShape {
82+ anchors {
83+ left: parent.left
84+ right: parent.right
85+ margins: (parent.width - root.padWidth) / 2
86+ }
87+ height: root.padHeight
88+ color: "#55000000"
89+ radius: "medium"
90+
91+ ThinDivider {
92+ anchors {
93+ left: parent.left
94+ right: parent.right
95+ top: parent.top
96+ topMargin: root.padHeight / 4
97+ }
98+ }
99+ ThinDivider {
100+ anchors {
101+ left: parent.left
102+ right: parent.right
103+ verticalCenter: parent.verticalCenter
104+ }
105+ }
106+ ThinDivider {
107+ anchors {
108+ left: parent.left
109+ right: parent.right
110+ bottom: parent.bottom
111+ bottomMargin: root.padHeight / 4
112+ }
113+ }
114+
115+ ThinDivider {
116+ anchors.centerIn: parent
117+ anchors.horizontalCenterOffset: -root.padWidth / 6
118+ width: root.padHeight
119+ rotation: -90
120+ }
121+ ThinDivider {
122+ anchors.centerIn: parent
123+ anchors.horizontalCenterOffset: root.padWidth / 6
124+ width: root.padHeight
125+ rotation: -90
126+ }
127+
128+ Grid {
129+ anchors {
130+ left: parent.left
131+ right: parent.right
132+ margins: (parent.width - root.padWidth) / 2
133+ }
134+
135+ columns: 3
136+
137+ Repeater {
138+ model: 9
139+
140+ PinPadButton {
141+ objectName: "pinPadButton" + (index + 1)
142+ width: root.padWidth / 3
143+ height: root.padHeight / 4
144+ text: index + 1
145+ enabled: entryEnabled
146+
147+ onClicked: {
148+ pinentryField.text = pinentryField.text + text;
149+ }
150+ }
151+ }
152+
153+ PinPadButton {
154+ objectName: "pinPadButtonBack"
155+ width: root.padWidth / 3
156+ height: root.padHeight / 4
157+ iconName: "back"
158+ onClicked: root.cancel();
159+ }
160+
161+ PinPadButton {
162+ objectName: "pinPadButton0"
163+ width: root.padWidth / 3
164+ height: root.padHeight / 4
165+ text: "0"
166+ onClicked: pinentryField.text = pinentryField.text + text
167+ enabled: entryEnabled
168+ }
169+
170+ PinPadButton {
171+ objectName: "pinPadButtonErase"
172+ width: root.padWidth / 3
173+ height: root.padHeight / 4
174+ iconName: "erase"
175+ onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
176+ enabled: entryEnabled
177+ }
178+ }
179+ }
180+
181+ WrongPasswordAnimation {
182+ id: wrongPasswordAnimation
183+ target: pinentryField
184+ }
185+}
Greeter/graphics/dot_empty.pngnew file

Binary file not shown.

Greeter/graphics/dot_filled.pngnew file

Binary file not shown.

Greeter/graphics/dot_pointer.pngnew file

Binary file not shown.

Greeter/graphics/icon_arrow.pngnew file

Binary file not shown.

Greeter/graphics/infographic_circle_back.pngnew file

Binary file not shown.

Hud/Hud.qmlnew file+496
@@ -0,0 +1,496 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import HudClient 0.1
20+
21+import "../Components"
22+
23+Item {
24+ id: hud
25+
26+ readonly property real elementsPadding: units.gu(1)
27+ readonly property real elementsYSliding: units.gu(2)
28+
29+ property alias revealerTarget: hudShowable
30+ property alias showAnimation: hudShowable.showAnimation
31+ property alias hideAnimation: hudShowable.hideAnimation
32+ property alias available: hudShowable.available
33+ property alias shown: hudShowable.shown
34+ property alias handleHeight: handle.height
35+
36+ readonly property variant outEasing: Easing.OutQuad
37+ readonly property variant inEasing: Easing.InQuad
38+ readonly property int animationDuration: 200
39+ readonly property int showableAnimationDuration: 100
40+ property bool showingOpenIndicator: false
41+
42+ // FIXME At the moment since we have no appstack
43+ // it's not possible to get results of the sidestage app
44+ // design has to come up with a solution
45+ function show() {
46+ hudShowable.show()
47+ }
48+ function hide() {
49+ hudShowable.hide()
50+ }
51+ function resetToInitialState() {
52+ hud.state = "initial"
53+ searchBar.unfocus()
54+ searchBar.text = ""
55+ parametrizedActionsPage.shown = false
56+ }
57+
58+ states: [
59+ State {
60+ name: "initial"
61+ PropertyChanges { target: searchBar; placeholderText: i18n.tr("Type or say a command") }
62+ PropertyChanges { target: searchBar; searchEnabled: true }
63+ PropertyChanges { target: toolBarAnimator; visible: true}
64+ AnchorChanges { target: searchBarAnimator; anchors.top: undefined; anchors.bottom: parent.bottom; }
65+ AnchorChanges { target: resultsCardAnimator; anchors.top: undefined; anchors.bottom: toolBarAnimator.top; }
66+ },
67+ State {
68+ name: "input" //only inherited by other states.
69+ AnchorChanges { target: searchBarAnimator; anchors.top: parent.top; anchors.bottom: undefined; }
70+ AnchorChanges { target: resultsCardAnimator; anchors.top: searchBarAnimator.bottom; anchors.bottom: undefined; }
71+ PropertyChanges { target: toolBarAnimator; visible: false }
72+ },
73+ State {
74+ name: "voice_input" //only inherited by other states.
75+ extend: "input"
76+ PropertyChanges { target: soundAmplitudeVisualAnimator; visible: true }
77+ PropertyChanges { target: resultsCardAnimator; visible: false }
78+ PropertyChanges { target: soundAmplitudeVisualAnimator; progress: 1 }
79+ PropertyChanges { target: searchBar; searchEnabled: false }
80+ },
81+ State {
82+ name: "voice_recognition_loading"
83+ extend: "voice_input"
84+ PropertyChanges { target: searchBar; placeholderText: i18n.tr("Loading. Please Wait...") }
85+ },
86+ State {
87+ name: "voice_recognition_listening"
88+ extend: "voice_input"
89+ PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speak Now...") }
90+ },
91+ State {
92+ name: "voice_recognition_processing"
93+ extend: "voice_input"
94+ PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speaking...") }
95+ },
96+ State {
97+ name: "showing_results"
98+ extend: "input"
99+ PropertyChanges { target: searchBar; placeholderText: i18n.tr("Type or say a command") }
100+ PropertyChanges { target: searchBar; searchEnabled: true }
101+ }
102+ ]
103+
104+ transitions: [
105+ Transition {
106+ from: "initial"
107+ to: "voice_recognition_loading"
108+ SequentialAnimation {
109+ NumberAnimation { // hide these components
110+ targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
111+ property: "progress"; duration: animationDuration; to: 0
112+ }
113+
114+ PropertyAction { targets: [toolBarAnimator, resultsCardAnimator]; property: "visible"; value: false}
115+ PropertyAction { target: soundAmplitudeVisualAnimator; property: "visible"; value: true}
116+
117+ AnchorAnimation { duration: 0 } // so anchor change happens at this point
118+
119+ NumberAnimation { // show these components
120+ targets: [searchBarAnimator, soundAmplitudeVisualAnimator]
121+ property: "progress"; duration: animationDuration; from: 0; to: 1
122+ }
123+ }
124+ },
125+ Transition {
126+ from: "showing_results"
127+ to: "voice_recognition_loading"
128+ SequentialAnimation {
129+ PropertyAction { target: soundAmplitudeVisualAnimator; property: "progress"; value: 0}
130+
131+ PropertyAction { // hide these components
132+ target: resultsCardAnimator; property: "progress"; value: 0
133+ }
134+
135+ NumberAnimation { // show these components
136+ target: soundAmplitudeVisualAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
137+ }
138+ }
139+ },
140+ Transition {
141+ from: "voice_recognition_processing"
142+ to: "showing_results"
143+ SequentialAnimation {
144+ NumberAnimation { // hide these components
145+ target: soundAmplitudeVisualAnimator; property: "progress"; duration: animationDuration; to: 0
146+ }
147+ PropertyAction { target: resultsCardAnimator; property: "visible"; value: true}
148+
149+ NumberAnimation { // show these components
150+ target: resultsCardAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
151+ }
152+ }
153+ },
154+ Transition {
155+ from: "initial"
156+ to: "showing_results"
157+ SequentialAnimation {
158+ NumberAnimation {
159+ targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
160+ property: "progress"; duration: animationDuration; to: 0
161+ }
162+
163+ PropertyAction { target: toolBarAnimator; property: "visible"; value: false}
164+
165+ AnchorAnimation { duration: 0 } // so anchor change happens at this point
166+
167+ NumberAnimation {
168+ targets: [searchBarAnimator, resultsCardAnimator]
169+ property: "progress"; duration: animationDuration; from: 0; to: 1
170+ }
171+ }
172+ }
173+ ]
174+
175+ state: "initial"
176+
177+ HudClient {
178+ id: hudClient
179+
180+ onCommandExecuted: {
181+ hudShowable.hide()
182+ }
183+
184+ onShowParametrizedAction: {
185+ parametrizedActionsPage.header = action
186+ parametrizedActionsPage.setItems(items)
187+ parametrizedActionsPage.shown = true
188+ }
189+
190+ onVoiceQueryLoading: {
191+ hud.state = "voice_recognition_loading"
192+ searchBar.ignoreNextTextChange = true
193+ searchBar.text = ""
194+ searchBar.unfocus()
195+ soundAmplitudeVisual.startIdle()
196+ }
197+ onVoiceQueryListening: {
198+ if (hud.state == "voice_recognition_loading" || hud.state == "showing_results") {
199+ searchBar.ignoreNextTextChange = true
200+ searchBar.text = ""
201+ searchBar.unfocus()
202+ hud.state = "voice_recognition_listening"
203+ }
204+ }
205+ onVoiceQueryHeardSomething: {
206+ if (hud.state == "voice_recognition_listening") {
207+ hud.state = "voice_recognition_processing"
208+ soundAmplitudeVisual.setDetectorEnabled(true)
209+ }
210+ }
211+ onVoiceQueryFinished: {
212+ hud.state = "showing_results"
213+ searchBar.text = query
214+ soundAmplitudeVisual.setDetectorEnabled(false)
215+ }
216+ onVoiceQueryFailed: {
217+ hud.state = "showing_results"
218+ searchBar.text = ""
219+ soundAmplitudeVisual.setDetectorEnabled(false)
220+ }
221+ }
222+
223+ Showable {
224+ id: hudShowable
225+ objectName: "hudShowable"
226+ height: parent.height
227+ width: parent.width
228+
229+ onYChanged: {
230+ if (greeter.shown) {
231+ showAnimation.duration = 0
232+ hideAnimation.duration = 0
233+ } else if (!showAnimation.running && !hideAnimation.running) {
234+ if (parent.height > 0) {
235+ showAnimation.duration = Math.min(showableAnimationDuration * (1 - (parent.height - y) / parent.height), showableAnimationDuration)
236+ hideAnimation.duration = showableAnimationDuration - showAnimation.duration
237+ }
238+ }
239+ }
240+
241+ MouseArea {
242+ // Eat everything that doesn't go to other places
243+ anchors.fill: parent
244+ }
245+
246+ Image {
247+ anchors.fill: parent
248+ fillMode: Image.Tile
249+ source: "graphics/hud_bg.png"
250+ }
251+
252+ Connections {
253+ target: hideAnimation
254+ onRunningChanged: {
255+ if (!hideAnimation.running) {
256+ showAnimation.duration = showableAnimationDuration
257+ hud.resetToInitialState()
258+ }
259+ }
260+ }
261+
262+ Connections {
263+ target: showAnimation
264+ onRunningChanged: {
265+ if (!showAnimation.running) {
266+ hideAnimation.duration = showableAnimationDuration
267+ }
268+ }
269+ }
270+ }
271+
272+ Item {
273+ id: handle
274+ objectName: "handle"
275+
276+ y: hudShowable.y
277+ anchors {
278+ left: parent.left
279+ right: parent.right
280+ }
281+ height: handleImage.height
282+
283+ Image {
284+ id: handleImage
285+ anchors {
286+ left: parent.left
287+ right: parent.right
288+ }
289+ source: "graphics/hud_handlebar.png"
290+ }
291+
292+ Image {
293+ id: handleArrow
294+ y: units.gu(1)
295+ anchors.horizontalCenter: parent.horizontalCenter
296+ source: "graphics/hud_handlearrow.png"
297+ cache: false
298+ }
299+ }
300+
301+ Item {
302+ id: hudContentClipper
303+
304+ anchors {
305+ left: parent.left
306+ right: parent.right
307+ bottom: parent.bottom
308+ top: handle.bottom
309+ }
310+ clip: visible && hudContent.height !== height
311+ visible: hudContent.height >= 0
312+
313+ Item {
314+ id: hudContent
315+ anchors {
316+ left: parent.left
317+ right: parent.right
318+ bottom: parent.bottom
319+ }
320+ height: hud.height
321+
322+ Item {
323+ id: mainPage
324+ x: parametrizedActionsPage.x - width
325+ height: hud.height
326+ width: hud.width
327+
328+ ShowingAnimation {
329+ id: toolBarAnimator
330+ objectName: "toolBarAnimator"
331+ anchors {
332+ left: parent.left
333+ right: parent.right
334+ bottom: searchBarAnimator.top
335+ margins: 2*elementsPadding //ensures positioning correct
336+ }
337+ progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
338+
339+ ToolBar {
340+ id: toolBar
341+ objectName: "toolBar"
342+ model: hudClient.toolBarModel
343+ anchors.horizontalCenter: parent.horizontalCenter
344+ onActionTriggered: {
345+ hudClient.executeToolBarAction(action)
346+ }
347+ }
348+ }
349+
350+ ShowingAnimation {
351+ id: searchBarAnimator
352+ objectName: "searchBarAnimator"
353+ anchors {
354+ left: parent.left
355+ right: parent.right
356+ bottom: parent.bottom
357+ margins: elementsPadding
358+ topMargin: handle.height + units.dp(1) + elementsPadding
359+ }
360+ progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
361+
362+ SearchBar {
363+ id: searchBar
364+ objectName: "searchBar"
365+
366+ property bool ignoreNextTextChange: false
367+
368+ anchors.left: parent.left
369+ anchors.right: parent.right
370+ height: units.gu(5)
371+
372+ placeholderText: i18n.tr("Type or say a command")
373+ activityIndicatorVisible: hud.state == "voice_recognition_processing"
374+
375+ onMicrophoneClicked: hudClient.startVoiceQuery()
376+
377+ onTextChanged: {
378+ if (ignoreNextTextChange) {
379+ ignoreNextTextChange = false
380+ } else {
381+ hudClient.setQuery(searchBar.text)
382+ }
383+ }
384+
385+ onTextFocused: {
386+ hud.state = "showing_results"
387+ }
388+ }
389+ }
390+
391+ ShowingAnimation {
392+ id: resultsCardAnimator
393+ objectName: "resultsCardAnimator"
394+
395+ anchors {
396+ left: parent.left
397+ right: parent.right
398+ top: searchBarAnimator.bottom
399+ margins: elementsPadding
400+ }
401+ progress: MathUtils.clamp((y - hudShowable.y + height - units.gu(8))/elementsYSliding, 0, 1)
402+
403+ Flickable {
404+ anchors.left: parent.left
405+ anchors.right: parent.right
406+ contentHeight: resultList.height
407+ contentWidth: width
408+ clip: height < contentHeight
409+ interactive: height < contentHeight
410+
411+ height: {
412+ if (hud.state == "showing_results") {
413+ return shell.applicationManager.keyboardVisible ? Math.min(hud.height - searchBarAnimator.y - searchBarAnimator.height - units.gu(2) - shell.applicationManager.keyboardHeight, contentHeight) : contentHeight
414+ } else {
415+ return contentHeight
416+ }
417+ }
418+
419+
420+ ResultList {
421+ id: resultList
422+
423+ anchors.left: parent.left
424+ anchors.right: parent.right
425+ height: childrenRect.height
426+
427+ onActivated: {
428+ hudClient.executeCommand(index)
429+ }
430+
431+ model: hudClient.results
432+ }
433+ }
434+ }
435+
436+ ShowingAnimation {
437+ id: soundAmplitudeVisualAnimator
438+
439+ anchors {
440+ horizontalCenter: parent.horizontalCenter
441+ verticalCenter: parent.verticalCenter
442+ verticalCenterOffset: (searchBar.height + 2*elementsPadding)/2
443+ }
444+ visible: false
445+ width: units.gu(33)
446+ progress: MathUtils.clamp((y - hudShowable.y - anchors.verticalCenterOffset)/elementsYSliding, 0, 1)
447+
448+ SoundAmplitudeVisual {
449+ id: soundAmplitudeVisual
450+ width: units.gu(33)
451+ height: width
452+ }
453+ }
454+ }
455+
456+ HudParametrizedActionsPage {
457+ id: parametrizedActionsPage
458+ objectName: "parametrizedActionsPage"
459+ property bool shown: false
460+
461+ anchors.bottom: parent.bottom
462+ height: hud.height - handle.height - units.dp(1)
463+ width: parent.width
464+ x: shown ? 0 : width
465+ onConfirmPressed: {
466+ hudClient.executeParametrizedAction(values())
467+ }
468+ onValuesUpdated: {
469+ hudClient.updateParametrizedAction(values())
470+ }
471+ onBackPressed: {
472+ shown = false
473+ }
474+ onShownChanged: {
475+ if (!shown) {
476+ hudClient.cancelParametrizedAction()
477+ }
478+ }
479+ Behavior on x {
480+ NumberAnimation {
481+ easing.type: outEasing
482+ duration: animationDuration
483+ }
484+ }
485+ }
486+ }
487+ }
488+
489+ Image {
490+ anchors.left: hudContentClipper.right
491+ anchors.top: hudContentClipper.top
492+ anchors.bottom: hudContentClipper.bottom
493+ fillMode: Image.Tile
494+ source: "graphics/dropshadow_right.png"
495+ }
496+}
Hud/HudParametrizedActionsPage.qmlnew file+172
@@ -0,0 +1,172 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+Item {
22+ property alias header: header.text
23+ signal backPressed
24+ signal confirmPressed
25+ signal valuesUpdated
26+ id: root
27+
28+ ListModel {
29+ id: actionItems
30+ }
31+
32+ function setItems(items) {
33+ while (actionItems.count > 0) {
34+ var item = actionItems.get(0).item
35+ actionItems.remove(0)
36+ item.visible = false
37+ item.destroy()
38+ }
39+
40+ var sliderCreator = Qt.createComponent("SliderLabel.qml");
41+ var first = true
42+ var topAnchor = header.bottom
43+ for (var i = 0; i < items.length; i++) {
44+ var item = items[i]
45+ if (item["parameter-type"] == "slider")
46+ {
47+ var slider = sliderCreator.createObject(flickableColumn);
48+ slider.anchors.left = flickableColumn.left
49+ slider.anchors.right = flickableColumn.right
50+ slider.anchors.topMargin = first ? units.gu(1) : units.gu(2)
51+ slider.anchors.top = topAnchor
52+ slider.tooltip = tooltip
53+ slider.sliderData = item
54+ topAnchor = slider.bottom
55+ actionItems.append({"item": slider})
56+ slider.onValueChanged.connect(valueChanged)
57+ }
58+ first = false
59+ }
60+ }
61+
62+ function valueChanged()
63+ {
64+ valuesUpdated()
65+ }
66+
67+ function values() {
68+ var values = {}
69+ for (var i = 0; i < actionItems.count; ++i) {
70+ var item = actionItems.get(i).item
71+ values[item.action] = item.value
72+ }
73+ return values
74+ }
75+
76+ Flickable {
77+ anchors.top: parent.top
78+ anchors.bottom: buttons.top
79+ anchors.left: parent.left
80+ anchors.right: parent.right
81+ clip: true
82+
83+ flickableDirection: Flickable.VerticalFlick
84+ interactive: !tooltip.visible
85+
86+ Item {
87+ id: flickableColumn
88+ anchors.top: parent.top
89+ anchors.left: parent.left
90+ anchors.right: parent.right
91+
92+ PageHeader {
93+ id: header
94+ anchors.top: parent.top
95+ anchors.left: parent.left
96+ anchors.right: parent.right
97+ anchors.topMargin: units.gu(1)
98+ }
99+ }
100+ }
101+ Item {
102+ id: buttons
103+ anchors.bottom: parent.bottom
104+ anchors.left: parent.left
105+ anchors.right: parent.right
106+ anchors.margins: units.gu(1)
107+ height: confirmButton.height
108+
109+ Button {
110+ id: backButton
111+ anchors.left: parent.left
112+ anchors.top: parent.top
113+ anchors.bottom: parent.bottom
114+ width: units.gu(7)
115+ color: "black"
116+ opacity: 0.25
117+ MouseArea {
118+ anchors.fill: parent
119+ onClicked: backPressed()
120+ }
121+ }
122+ Image {
123+ anchors.centerIn: backButton
124+ source: "graphics/icon_arrow.png"
125+ }
126+
127+ Button {
128+ id: confirmButton
129+ anchors.right: parent.right
130+ width: units.gu(13)
131+ height: units.gu(5)
132+ text: i18n.tr("Confirm")
133+ color: "#F05D22"
134+ onClicked: confirmPressed()
135+ }
136+ }
137+
138+ Item {
139+ id: tooltip
140+ property variant target: undefined
141+ visible: target != undefined
142+ y: visible ? root.mapFromItem(target.parent, 0, target.y).y - height : 0
143+ x: visible ? target.anchors.leftMargin + target.__internals.thumb.x + target.__internals.thumb.width / 2 - width / 2 : 0
144+
145+ width: childrenRect.width
146+ height: childrenRect.height
147+
148+ Rectangle {
149+ id: tooltipRectangle
150+ width: units.gu(8)
151+ height: units.gu(6)
152+ color: "white"
153+ radius: units.gu(0.5)
154+
155+ Label {
156+ anchors.fill: parent
157+ text: tooltip.target ? tooltip.target.realFormatValue(tooltip.target.value) : ""
158+ horizontalAlignment: Text.AlignHCenter
159+ verticalAlignment: Text.AlignVCenter
160+ fontSize: "large"
161+ }
162+ }
163+ Image {
164+ id: tooltipTip
165+ source: "graphics/popup_triangle.png"
166+
167+ anchors.top: tooltipRectangle.bottom
168+ anchors.horizontalCenter: parent.horizontalCenter
169+ }
170+
171+ }
172+}
Hud/Result.qmlnew file+84
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ property string contextSnippetText
22+ property variant contextSnippetHighlights
23+ property string nameText
24+ property variant nameHighlights
25+
26+ function highlightedText(text, highlights) {
27+ var hText = "";
28+ var nextIndexToProcess = 0;
29+ if (highlights && highlights.length % 2 == 0) {
30+ for (var i = 0; i < highlights.length - 1; i += 2) {
31+ var highlightStart = highlights[i];
32+ var highlightEnd = highlights[i + 1];
33+ if (highlightEnd < highlightStart)
34+ continue;
35+ if (highlightStart < nextIndexToProcess)
36+ continue;
37+ if (highlightStart != nextIndexToProcess) {
38+ // Prev non marked text
39+ hText += text.substr(nextIndexToProcess, highlightStart - nextIndexToProcess);
40+ }
41+
42+ // Marked text
43+ hText += "<font color=\"#ffffff\">" + text.substr(highlightStart, highlightEnd - highlightStart + 1) + "</font>";
44+ nextIndexToProcess = highlightEnd + 1;
45+ }
46+ }
47+ if (nextIndexToProcess != text.length) {
48+ // End non marked text
49+ hText += text.substr(nextIndexToProcess);
50+ }
51+ return hText;
52+ }
53+
54+ Label {
55+ id: actionLabel
56+ objectName: "actionLabel"
57+ anchors.left: parent.left
58+ anchors.leftMargin: units.gu(1)
59+ anchors.verticalCenter: parent.verticalCenter
60+ width: parent.width / 2
61+ fontSize: "medium"
62+ elide: Text.ElideRight
63+ maximumLineCount: 1
64+ text: highlightedText(nameText, nameHighlights)
65+ color: "#80ffffff"
66+ }
67+
68+ Label {
69+ horizontalAlignment: Text.AlignRight
70+ id: contextSnippetLabel
71+ objectName: "contextSnippetLabel"
72+ width: parent.width / 2 - units.gu(1)
73+ visible: text != ""
74+ anchors.right: parent.right
75+ anchors.rightMargin: units.gu(1)
76+ anchors.verticalCenter: parent.verticalCenter
77+ fontSize: "small"
78+ opacity: 0.5
79+ elide: Text.ElideRight
80+ maximumLineCount: 2
81+ text: highlightedText(contextSnippetText, contextSnippetHighlights)
82+ color: "#80ffffff"
83+ }
84+}
Hud/ResultList.qmlnew file+106
@@ -0,0 +1,106 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Column {
21+ property var model: undefined
22+
23+ // Hud gives lots of results, make sure we have 5 at most
24+ // FIXME This should use SortFilterProxyModel
25+ // but there is a problem with the hud-service refreshing the
26+ // data for no reason so we use the internal model + timer
27+ // to fix those issues
28+ ListModel {
29+ id: internalModel
30+ }
31+
32+ Connections {
33+ target: model
34+ // Accumulate count changes since hud clears
35+ // and then readds items to the models which means
36+ // even if the result is the same we get lots of count changes
37+ onCountChanged: updateModelTimer.restart()
38+ }
39+
40+ onModelChanged: updateModelTimer.restart()
41+
42+ Timer {
43+ id: updateModelTimer
44+ interval: 30
45+ onTriggered: updateModel()
46+ }
47+
48+ function updateModel() {
49+ internalModel.clear()
50+ for (var i = 0; i < 5 && i < model.count; ++i) {
51+ var itemData = model.get(i)
52+ internalModel.append({"name": itemData.column_1, "highlights": itemData.column_2, "context": itemData.column_3, "contextHighlights": itemData.column_4})
53+ }
54+ }
55+
56+ signal activated(int index)
57+
58+ height: repeater.height
59+
60+ Repeater {
61+ id: repeater
62+ objectName: "resultListRepeater"
63+ model: internalModel
64+
65+ delegate: MouseArea {
66+ id: delegate
67+ height: result.height + separatorLine.height * 2
68+ anchors.left: parent.left
69+ anchors.right: parent.right
70+
71+ onClicked: activated(index)
72+
73+ BorderImage {
74+ id: separatorLine
75+ anchors.top: parent.top
76+ anchors.left: parent.left
77+ anchors.right: parent.right
78+ source: "graphics/divider.sci"
79+ visible: index == 0
80+ }
81+
82+ Result {
83+ id: result
84+ height: units.gu(6)
85+ anchors.top: separatorLine.bottom
86+ anchors.left: parent.left
87+ anchors.right: parent.right
88+
89+ nameText: name
90+ nameHighlights: highlights
91+ contextSnippetText: context
92+ contextSnippetHighlights: contextHighlights
93+ }
94+
95+ BorderImage {
96+ anchors.top: result.bottom
97+ anchors.left: parent.left
98+ anchors.right: parent.right
99+ source: "graphics/divider.sci"
100+ }
101+
102+ Component.onCompleted: fadeIn.start()
103+ NumberAnimation { id: fadeIn; target: resultList; alwaysRunToEnd: true; property: "opacity"; duration: 200; from: 0; to: 1 }
104+ }
105+ }
106+}
Hud/SearchBar.qmlnew file+100
@@ -0,0 +1,100 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ id: root
22+ property alias activityIndicatorVisible: activityIndicator.visible
23+ property alias text: searchBar.text
24+ property alias placeholderText: searchBar.placeholderText
25+ property alias searchEnabled: searchBar.enabled
26+ signal microphoneClicked
27+ signal textFocused
28+
29+ readonly property real imageSize: units.gu(3)
30+
31+ function unfocus()
32+ {
33+ searchBar.focus = false
34+ }
35+
36+ ActivityIndicator {
37+ id: activityIndicator
38+ height: imageSize
39+ width: height
40+ x: magnifierImage.x
41+ y: magnifierImage.y
42+ running: visible
43+ }
44+
45+ TextField {
46+ id: searchBar
47+ anchors.fill: parent
48+
49+ hasClearButton: false
50+ font.pixelSize: FontUtils.sizeToPixels("large")
51+
52+ onActiveFocusChanged: {
53+ if (activeFocus) {
54+ root.textFocused()
55+ }
56+ }
57+
58+ Item {
59+ id: primary
60+ height: searchBar.height
61+ width: height
62+
63+ Image {
64+ id: magnifierImage
65+ height: imageSize
66+ width: height
67+ anchors.centerIn: parent
68+ source: "graphics/icon_search.png"
69+ visible: !activityIndicator.visible && !clearImage.visible
70+ }
71+
72+ Image {
73+ id: clearImage
74+ height: imageSize
75+ width: height
76+ anchors.centerIn: parent
77+ source: "graphics/icon_clear.png"
78+ visible: !activityIndicator.visible && searchBar.text != ""
79+ MouseArea {
80+ anchors.fill: parent
81+ onClicked: searchBar.text = ""
82+ }
83+ }
84+ }
85+
86+ primaryItem: primary
87+ secondaryItem: MouseArea {
88+ height: searchBar.height
89+ width: height
90+ onClicked: microphoneClicked()
91+
92+ Image {
93+ height: imageSize
94+ width: height
95+ anchors.centerIn: parent
96+ source: "graphics/microphone.png"
97+ }
98+ }
99+ }
100+}
Hud/ShowingAnimation.qmlnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+Item {
22+ id: root
23+ property real yOffsetAtAnimationStart: units.gu(2)
24+ property real progress: 0
25+ property int animationDuration: 200
26+ default property alias __itemsToAnimate: container.children
27+
28+ property bool showing: progress > 0
29+
30+ height: childrenRect.height
31+
32+ Item {
33+ id: container
34+ anchors {
35+ left: parent.left
36+ right: parent.right
37+ }
38+ height: childrenRect.height
39+ }
40+
41+ NumberAnimation {id: opacityAnimation; target: container; property: "opacity"; from: 0; to: 1; duration: animationDuration}
42+ NumberAnimation {id: yAnimation; target: container; property: "y"; from: yOffsetAtAnimationStart; to: 0; duration: animationDuration}
43+
44+ // FIXME This would much more sense in a ParallelAnimation and just
45+ // one AnimationController but that goes something crazy and rendering never stops
46+ AnimationController {
47+ animation: opacityAnimation
48+ progress: root.progress
49+ }
50+ AnimationController {
51+ animation: yAnimation
52+ progress: root.progress
53+ }
54+}
Hud/SliderLabel.qmlnew file+74
@@ -0,0 +1,74 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+Item {
21+ height: childrenRect.height
22+ width: childrenRect.width
23+ property variant tooltip
24+
25+ property variant sliderData
26+ property string action
27+ property alias value: slider.value
28+ onValueChanged: {
29+ // TODO We should not need this but without it
30+ // slider.onValueChanged.connect(valueChanged) in
31+ // HudParametrizedActionsPage.qml doesn't work
32+ // Michael thinks it's related to https://bugreports.qt-project.org/browse/QTBUG-29141
33+ }
34+
35+ onSliderDataChanged: {
36+ label.text = sliderData["label"]
37+ slider.minimumValue = sliderData["min"]
38+ slider.maximumValue = sliderData["max"]
39+ slider.live = sliderData["live"]
40+ // SDK Slider does not support step yet
41+// slider.step = sliderData["step"]
42+ slider.value = sliderData["value"]
43+ action = sliderData["action"]
44+ }
45+
46+ Label {
47+ id: label
48+ anchors.top: parent.top
49+ anchors.left: parent.left
50+ anchors.right: parent.right
51+ anchors.margins: units.gu(1)
52+ anchors.leftMargin: units.gu(2)
53+ color: "white"
54+ }
55+ Slider {
56+ id: slider
57+ anchors.top: label.bottom
58+ anchors.left: parent.left
59+ anchors.right: parent.right
60+ anchors.margins: units.gu(1)
61+ height: units.gu(6)
62+ live: true
63+ function realFormatValue(v) { return Math.round(v) + " %" }
64+ function formatValue(v) { return tooltip.target == slider ? "" : realFormatValue(v) }
65+ onPressedChanged: tooltip.target = pressed ? slider : undefined
66+ }
67+ BorderImage {
68+ source: "graphics/divider.sci"
69+ anchors.top: slider.bottom
70+ anchors.left: parent.left
71+ anchors.right: parent.right
72+ anchors.topMargin: units.gu(2)
73+ }
74+}
Hud/SoundAmplitudeDelegate.qmlnew file+52
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+Rectangle {
20+ id: delegate
21+ property real amplitude: 0
22+ property int totalCount
23+ property int ballIndex
24+ width: {
25+ var t = amplitude / 0.6
26+ t = -t * (t - 2)
27+ return units.gu(0.25) + units.gu(5) * t
28+ }
29+ visible: amplitude != 0
30+ height: width
31+ color: "#DD4814"
32+ radius: width * 0.5
33+ antialiasing: true
34+ opacity: {
35+ // TODO This formula has hardocded values everywhere :D
36+ var t
37+ var dampenAfterThisIndex = 7
38+ if (ballIndex < dampenAfterThisIndex) {
39+ t = (totalCount - ballIndex) / totalCount
40+ return Math.pow(t, 4);
41+ } else {
42+ t = (totalCount - dampenAfterThisIndex) / totalCount
43+ t = Math.pow(t, 4);
44+ t = t * 0.7;
45+ return 0.09 + t * (totalCount - ballIndex) / (totalCount - dampenAfterThisIndex)
46+ }
47+ }
48+
49+ property double orbitRadius: ((parent.width - units.gu(6)) / 2)
50+ x: -(width / 2) + (parent.width / 2) + orbitRadius * Math.sin((ballIndex / totalCount) * (2 * Math.PI))
51+ y: -(height / 2) + (parent.height / 2) - orbitRadius * Math.cos((ballIndex / totalCount) * (2 * Math.PI))
52+}
Hud/SoundAmplitudeVisual.qmlnew file+146
@@ -0,0 +1,146 @@
1+/*
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import HudClient 0.1
19+
20+Item {
21+ id: voiceInput
22+
23+ readonly property int totalSpots: 30
24+ readonly property int totalIdles: 7
25+
26+ property real __newPeak: 0
27+
28+ VolumePeakDetector {
29+ id: peakDetector
30+ desiredInterval: peakMover.interval
31+ onNewPeak: {
32+ __newPeak = volume
33+ }
34+ }
35+
36+ Timer {
37+ id: peakMover
38+ interval: 10
39+ repeat: true
40+ onTriggered: {
41+ moveBalls()
42+ voiceAmplitudes.itemAt(0).amplitude = __newPeak
43+ }
44+ }
45+
46+ Repeater {
47+ id: fixedPositionSoundAmplitudes
48+ model: totalSpots
49+ delegate: SoundAmplitudeDelegate {
50+ totalCount: fixedPositionSoundAmplitudes.count
51+ ballIndex: index
52+ opacity: 1
53+ visible: true
54+ }
55+ }
56+
57+ Repeater {
58+ id: voiceAmplitudes
59+ model: totalSpots
60+ delegate: SoundAmplitudeDelegate {
61+ totalCount: voiceAmplitudes.count
62+ ballIndex: index
63+ }
64+ }
65+
66+ Repeater {
67+ id: idleAmplitudes
68+ model: totalSpots
69+ delegate: SoundAmplitudeDelegate {
70+ totalCount: idleAmplitudes.count
71+ ballIndex: index
72+ amplitude: 0.05
73+ visible: idleAmplitudes.enabled
74+ }
75+ }
76+
77+ function setDetectorEnabled(enabled) {
78+ idleAmplitudes.enabled = false
79+ if (enabled) {
80+ peakMover.start()
81+ } else {
82+ peakDetector.enabled = false
83+ peakMover.stop()
84+ }
85+ }
86+
87+ function moveBalls() {
88+ var i = 0
89+ var amplitude = voiceAmplitudes.itemAt(0).amplitude
90+ for (var i = 1; i < totalSpots; ++i) {
91+ var item = voiceAmplitudes.itemAt(i)
92+ var tempAmplitude = item.amplitude
93+ item.amplitude = amplitude
94+ amplitude = tempAmplitude
95+ }
96+ }
97+
98+ property int __firstIdle
99+ property int __idleCount
100+
101+ Timer {
102+ id: idleBallsTimer
103+ interval: 40
104+ onTriggered: moveAndAddIdleBalls()
105+ }
106+
107+ function moveAndAddIdleBalls() {
108+ // Check if we are doing the real thing
109+ if (!idleAmplitudes.enabled) {
110+ return
111+ }
112+
113+ for (var i = 0; i < __idleCount; ++i) {
114+ var index = __firstIdle - i
115+ var item = idleAmplitudes.itemAt(index % totalSpots)
116+ var nextItem = idleAmplitudes.itemAt((index + 1) % totalSpots)
117+ nextItem.opacity = item.opacity
118+ }
119+ __firstIdle++
120+ idleAmplitudes.itemAt((__firstIdle - __idleCount) % totalSpots).opacity = 0
121+
122+ if (__idleCount < totalIdles) {
123+ idleAmplitudes.itemAt(0).opacity = 1 - (__idleCount / totalIdles)
124+ __idleCount++
125+ }
126+ idleBallsTimer.start()
127+ }
128+
129+ function startIdle() {
130+ // On the device the peak detector takes quite a lot to start up
131+ // so enable it as soon as we know we are going to do voice capture
132+ peakDetector.enabled = true
133+ for (var i = 0; i < totalSpots; ++i) {
134+ idleAmplitudes.itemAt(i).opacity = 0
135+ }
136+ for (var i = 0; i < totalSpots; ++i) {
137+ voiceAmplitudes.itemAt(i).amplitude = 0
138+ }
139+
140+ idleAmplitudes.enabled = true
141+ idleAmplitudes.itemAt(0).opacity = 1
142+ __idleCount = 1
143+ __firstIdle = 0
144+ idleBallsTimer.start()
145+ }
146+}
tests/mocks/Utils/URLDispatcher.cpp → Hud/ToolBar.qmlrenamed+14−19
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2016 Canonical, Ltd.
2+ * Copyright (C) 2012, 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,25 +14,20 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#include "URLDispatcher.h"
17+import QtQuick 2.0
18+import HudClient 0.1
18
19
19−#include <QDBusConnection>
20+Row {
21+ signal actionTriggered(int action)
22+ property alias model: repeater.model
20
23
21−URLDispatcher::URLDispatcher(QObject *parent)
24+ spacing: units.gu(3)
22− : QObject(parent)
25+ Repeater {
23− , m_active(false)
26+ id: repeater
24−{
27+ ToolBarIcon {
25−}
28+ source: model.iconPath
26−
29+ onClicked: actionTriggered(model.action)
27−bool URLDispatcher::active() const
30+ enabled: model.enabled
28−{
31+ }
29− return m_active;
30−}
31−
32−void URLDispatcher::setActive(bool value)
33−{
34− if (m_active != value) {
35− m_active = value;
36− Q_EMIT activeChanged();
37 }
32 }
38}
33}
Hud/ToolBarIcon.qmlnew file+32
@@ -0,0 +1,32 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+
20+AbstractButton {
21+ property alias source: image.source
22+
23+ height: units.gu(4)
24+ width: height
25+ opacity: enabled ? 1 : 0.5
26+ Behavior on opacity { NumberAnimation { duration: 150 } }
27+
28+ Image {
29+ id: image
30+ anchors.fill: parent
31+ }
32+}
Hud/graphics/divider@20.pngnew file

Binary file not shown.

Hud/graphics/divider@20.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 0
2+border.top: 0
3+border.bottom: 0
4+border.right: 2
5+source: divider@20.png
Hud/graphics/dropshadow_right@20.pngnew file

Binary file not shown.

Hud/graphics/help@20.pngnew file

Binary file not shown.

Hud/graphics/hud_bg@20.pngnew file

Binary file not shown.

Hud/graphics/hud_handlearrow@20.pngnew file

Binary file not shown.

Hud/graphics/hud_handlebar@20.pngnew file

Binary file not shown.

Hud/graphics/icon_arrow@20.pngnew file

Binary file not shown.

Hud/graphics/icon_clear@20.pngnew file

Binary file not shown.

Hud/graphics/icon_search@20.pngnew file

Binary file not shown.

Hud/graphics/microphone@20.pngnew file

Binary file not shown.

Hud/graphics/popup_triangle@20.pngnew file

Binary file not shown.

Hud/graphics/settings@20.pngnew file

Binary file not shown.

Hud/graphics/undo@20.pngnew file

Binary file not shown.

Hud/graphics/view-fullscreen@20.pngnew file

Binary file not shown.

Jenkinsfiledeleted−2
@@ -1,2 +0,0 @@
1−@Library('ubports-build-tools') _
2−buildAndProvideDebianPackage()
qml/Launcher/FoldingLauncherDelegate.qml → Launcher/FoldingLauncherDelegate.qmlrenamed+2−2
@@ -14,8 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19
19
20LauncherDelegate {
20LauncherDelegate {
21 id: root
21 id: root
Launcher/Launcher.qmlnew file+253
@@ -0,0 +1,253 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import "../Components"
19+import Ubuntu.Components 0.1
20+import Ubuntu.Gestures 0.1
21+import Unity 0.1
22+import Unity.Launcher 0.1
23+
24+Item {
25+ id: root
26+
27+ property bool available: true // can be used to disable all interactions
28+
29+ property int panelWidth: units.gu(8)
30+ property int dragAreaWidth: units.gu(1)
31+ property int minimizeDistance: units.gu(26)
32+ property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
33+ (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
34+
35+ readonly property bool shown: panel.x > -panel.width
36+
37+ // emitted when an application is selected
38+ signal launcherApplicationSelected(string appId)
39+
40+ // emitted when the apps dash should be shown because of a swipe gesture
41+ signal dash()
42+
43+ // emitted when the dash icon in the launcher has been tapped
44+ signal dashItemSelected()
45+
46+ onStateChanged: {
47+ if (state == "") {
48+ dismissTimer.stop()
49+ } else {
50+ dismissTimer.restart()
51+ }
52+ }
53+
54+ function hide() {
55+ switchToNextState("")
56+ }
57+
58+ function switchToNextState(state) {
59+ animateTimer.nextState = state
60+ animateTimer.start();
61+ }
62+
63+ function tease() {
64+ if (available) {
65+ teaseTimer.start();
66+ }
67+ }
68+
69+ Timer {
70+ id: teaseTimer
71+ interval: 200
72+ }
73+
74+ Timer {
75+ id: dismissTimer
76+ interval: 5000
77+ onTriggered: {
78+ if (!panel.preventHiding) {
79+ root.state = ""
80+ } else {
81+ dismissTimer.restart()
82+ }
83+ }
84+ }
85+
86+ // Because the animation on x is disabled while dragging
87+ // switching state directly in the drag handlers would not animate
88+ // the completion of the hide/reveal gesture. Lets update the state
89+ // machine and switch to the final state in the next event loop run
90+ Timer {
91+ id: animateTimer
92+ interval: 1
93+ property string nextState: ""
94+ onTriggered: {
95+ // switching to an intermediate state here to make sure all the
96+ // values are restored, even if we were already in the target state
97+ root.state = "tmp"
98+ root.state = nextState
99+ }
100+ }
101+
102+ MouseArea {
103+ id: launcherDragArea
104+ enabled: root.state == "visible"
105+ anchors.fill: panel
106+ anchors.rightMargin: -units.gu(2)
107+ drag {
108+ axis: Drag.XAxis
109+ maximumX: 0
110+ target: panel
111+ }
112+
113+ onReleased: {
114+ if (panel.x < -panel.width/3) {
115+ root.switchToNextState("")
116+ } else {
117+ root.switchToNextState("visible")
118+ }
119+ }
120+
121+ }
122+ MouseArea {
123+ id: closeMouseArea
124+ anchors {
125+ left: launcherDragArea.right
126+ top: parent.top
127+ right: parent.right
128+ bottom: parent.bottom
129+ }
130+ enabled: root.state == "visible"
131+ onPressed: {
132+ root.state = ""
133+ }
134+ }
135+
136+ Rectangle {
137+ id: backgroundShade
138+ anchors.fill: parent
139+ color: "black"
140+ opacity: root.state == "visible" ? 0.6 : 0
141+
142+ Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.BriskDuration } }
143+ }
144+
145+ LauncherPanel {
146+ id: panel
147+ objectName: "launcherPanel"
148+ enabled: root.available
149+ width: root.panelWidth
150+ anchors {
151+ top: parent.top
152+ bottom: parent.bottom
153+ }
154+ x: -width
155+ opacity: (x == -width && dragArea.status === DirectionalDragArea.WaitingForTouch) ? 0 : 1
156+ model: LauncherModel
157+
158+ property bool animate: true
159+
160+ onApplicationSelected: {
161+ root.state = ""
162+ launcherApplicationSelected(appId)
163+ }
164+ onDashItemSelected: {
165+ root.state = ""
166+ root.dashItemSelected(index)
167+ }
168+
169+ onPreventHidingChanged: {
170+ if (dismissTimer.running) {
171+ dismissTimer.restart();
172+ }
173+ }
174+
175+ Behavior on x {
176+ NumberAnimation {
177+ // Disabling animation when dragging
178+ duration: dragArea.dragging || launcherDragArea.drag.active ? 0 : 300;
179+ easing.type: Easing.OutCubic
180+ }
181+ }
182+
183+ Behavior on opacity {
184+ NumberAnimation {
185+ duration: UbuntuAnimation.FastDuration; easing.type: Easing.OutCubic
186+ }
187+ }
188+ }
189+
190+ EdgeDragArea {
191+ id: dragArea
192+
193+ direction: Direction.Rightwards
194+
195+ enabled: root.available
196+ width: root.dragAreaWidth
197+ height: root.height
198+
199+ onTouchXChanged: {
200+ if (status !== DirectionalDragArea.Recognized || launcher.state == "visible")
201+ return;
202+
203+ // When the gesture finally gets recognized, the finger will likely be
204+ // reasonably far from the edge. If we made the panel immediately
205+ // follow the finger position it would be visually unpleasant as it
206+ // would appear right next to the user's finger out of nowhere.
207+ // Instead, we make the panel go towards the user's finger in several
208+ // steps. ie., in an animated way.
209+ var targetPanelX = Math.min(0, touchX - panel.width)
210+ var delta = targetPanelX - panel.x
211+ // the trick is not to go all the way (1.0) as it would cause a sudden jump
212+ panel.x += 0.4 * delta
213+ }
214+
215+ onDraggingChanged: {
216+ if (!dragging) {
217+ if (distance > panel.width / 2) {
218+ root.switchToNextState("visible")
219+ if (distance > minimizeDistance) {
220+ root.dash()
221+ }
222+ } else {
223+ root.switchToNextState("")
224+ }
225+ }
226+ }
227+ }
228+
229+ states: [
230+ State {
231+ name: "" // hidden state. Must be the default state ("") because "when:" falls back to this.
232+ PropertyChanges {
233+ target: panel
234+ x: -root.panelWidth
235+ }
236+ },
237+ State {
238+ name: "visible"
239+ PropertyChanges {
240+ target: panel
241+ x: 0
242+ }
243+ },
244+ State {
245+ name: "teasing"
246+ when: teaseTimer.running
247+ PropertyChanges {
248+ target: panel
249+ x: -root.panelWidth + units.gu(2)
250+ }
251+ }
252+ ]
253+}
qml/Launcher/LauncherDelegate.qml → Launcher/LauncherDelegate.qmlrenamed+54−167
@@ -14,26 +14,19 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Components 1.3
18+import Ubuntu.Components 0.1
19
19
20Item {
20Item {
21 id: root
21 id: root
22
22
23− property int itemIndex: 0
24 property string iconName
23 property string iconName
25− property string name
26− property int count: 0
24+ property int count: -1
27− property bool countVisible: false
28 property int progress: -1
25 property int progress: -1
29− property bool itemRunning: false
26+ property bool highlighted: false
30 property bool itemFocused: false
27 property bool itemFocused: false
31 property real maxAngle: 0
28 property real maxAngle: 0
32 property bool inverted: false
29 property bool inverted: false
33− property bool alerting: false
34− property bool highlighted: false
35− property bool shortcutHintShown: false
36− property int surfaceCount: 1
37
30
38 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
31 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
39 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
32 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
@@ -46,144 +39,84 @@ Item {
46 property real offset: 0
39 property real offset: 0
47 property real itemOpacity: 1
40 property real itemOpacity: 1
48 property real brightness: 0
41 property real brightness: 0
49− property double maxWiggleAngle: 5.0
50
42
51− QtObject {
43+ onIconNameChanged: shaderEffectSource.scheduleUpdate();
52− id: priv
44+ onCountChanged: shaderEffectSource.scheduleUpdate();
53−
45+ onProgressChanged: shaderEffectSource.scheduleUpdate();
54− readonly property int wiggleDuration: UbuntuAnimation.SnapDuration
46+ onHighlightedChanged: shaderEffectSource.scheduleUpdate();
55− property real wiggleAngle: 0
47+ onItemFocusedChanged: shaderEffectSource.scheduleUpdate();
56− }
57−
58− readonly property var wiggleAnim: SequentialAnimation {
59−
60− running: alerting
61− loops: 1
62− alwaysRunToEnd: true
63−
64− NumberAnimation {
65− target: priv
66− property: "wiggleAngle"
67− from: 0
68− to: maxWiggleAngle
69− duration: priv.wiggleDuration
70− easing.type: Easing.InQuad
71− }
72−
73− NumberAnimation {
74− target: priv
75− property: "wiggleAngle"
76− from: maxWiggleAngle
77− to: -maxWiggleAngle
78− duration: priv.wiggleDuration
79− easing.type: Easing.InOutQuad
80− }
81−
82− NumberAnimation {
83− target: priv
84− property: "wiggleAngle"
85− from: -maxWiggleAngle
86− to: maxWiggleAngle
87− duration: priv.wiggleDuration
88− easing.type: Easing.InOutQuad
89− }
90−
91− NumberAnimation {
92− target: priv
93− property: "wiggleAngle"
94− from: maxWiggleAngle
95− to: -maxWiggleAngle
96− duration: priv.wiggleDuration
97− easing.type: Easing.InOutQuad
98− }
99−
100− NumberAnimation {
101− target: priv
102− property: "wiggleAngle"
103− from: -maxWiggleAngle
104− to: maxWiggleAngle
105− duration: priv.wiggleDuration
106− easing.type: Easing.InOutQuad
107− }
108−
109− NumberAnimation {
110− target: priv
111− property: "wiggleAngle"
112− from: maxWiggleAngle
113− to: 0
114− duration: priv.wiggleDuration
115− easing.type: Easing.OutQuad
116− }
117− }
118
48
119 Item {
49 Item {
120 id: iconItem
50 id: iconItem
121− width: root.width
51+ width: parent.itemWidth + units.gu(1)
122 height: parent.itemHeight + units.gu(1)
52 height: parent.itemHeight + units.gu(1)
123 anchors.centerIn: parent
53 anchors.centerIn: parent
124
54
125− StyledItem {
55+ UbuntuShape {
126− styleName: "FocusShape"
127− anchors.fill: iconShape
128− activeFocusOnTab: true
129− StyleHints {
130− visible: root.highlighted
131− radius: units.gu(2.55)
132− }
133− }
134−
135− ProportionalShape {
136 id: iconShape
56 id: iconShape
137− anchors.centerIn: parent
57+ anchors.fill: parent
138− width: root.itemWidth
58+ anchors.margins: units.gu(1)
139− aspect: UbuntuShape.DropShadow
59+ radius: "medium"
60+
140− source: Image {
61+ image: Image {
141 id: iconImage
62 id: iconImage
142 sourceSize.width: iconShape.width
63 sourceSize.width: iconShape.width
143 sourceSize.height: iconShape.height
64 sourceSize.height: iconShape.height
144 source: root.iconName
65 source: root.iconName
145− cache: false // see lpbug#1543290 why no cache
146 }
66 }
147 }
67 }
148
68
149− UbuntuShape {
69+ BorderImage {
150− id: countEmblem
70+ id: overlayHighlight
71+ anchors.centerIn: iconItem
72+ rotation: inverted ? 180 : 0
73+ source: root.highlighted ? "graphics/selected.sci" : "graphics/non-selected.sci"
74+ width: root.itemWidth + units.gu(0.5)
75+ height: root.itemHeight + units.gu(0.5)
76+ }
77+
78+ BorderImage {
151 objectName: "countEmblem"
79 objectName: "countEmblem"
152 anchors {
80 anchors {
153 right: parent.right
81 right: parent.right
154− bottom: parent.bottom
82+ top: parent.top
155− rightMargin: (iconItem.width - root.itemWidth) / 2 - units.dp(2)
156− margins: units.dp(5)
83+ margins: units.dp(3)
157 }
84 }
158− width: Math.min(root.itemWidth, Math.max(units.gu(2), countLabel.implicitWidth + units.gu(1)))
85+ width: Math.min(root.itemWidth, Math.max(units.gu(3), countLabel.implicitWidth + units.gu(2.5)))
159− height: units.gu(2)
86+ height: units.gu(3)
160− backgroundColor: theme.palette.normal.positive
87+ source: "graphics/notification.sci"
161− visible: root.countVisible
88+ visible: root.count > 0
162− aspect: UbuntuShape.Flat
163
89
164 Label {
90 Label {
165 id: countLabel
91 id: countLabel
166− objectName: "countLabel"
167 text: root.count
92 text: root.count
168 anchors.centerIn: parent
93 anchors.centerIn: parent
169 width: root.itemWidth - units.gu(1)
94 width: root.itemWidth - units.gu(1)
170 horizontalAlignment: Text.AlignHCenter
95 horizontalAlignment: Text.AlignHCenter
171 elide: Text.ElideRight
96 elide: Text.ElideRight
172 color: "white"
97 color: "white"
173− fontSize: "x-small"
98+ fontSize: "small"
99+ font.bold: true
174 }
100 }
175 }
101 }
176
102
177− UbuntuShape {
103+ BorderImage {
178 id: progressOverlay
104 id: progressOverlay
179 objectName: "progressOverlay"
105 objectName: "progressOverlay"
180−
181− anchors.centerIn: parent
106+ anchors {
182− width: root.itemWidth * .8
107+ left: iconItem.left
108+ right: iconItem.right
109+ bottom: iconItem.bottom
110+ leftMargin: units.gu(1)
111+ rightMargin: units.gu(1)
112+ bottomMargin: units.gu(1)
113+ }
183− height: units.dp(3)
114+ height: units.gu(1.5)
184 visible: root.progress > -1
115 visible: root.progress > -1
185− backgroundColor: "white"
116+ source: "graphics/progressbar-trough.sci"
186− borderSource: "none"
117+
118+ // For fill calculation we need to remove the 2 units of border defined in .sci file
119+ property int adjustedWidth: width - units.gu(2)
187
120
188 Item {
121 Item {
189 anchors {
122 anchors {
@@ -191,67 +124,28 @@ Item {
191 top: parent.top
124 top: parent.top
192 bottom: parent.bottom
125 bottom: parent.bottom
193 }
126 }
194− width: Math.min(100, root.progress) / 100 * parent.width
127+ width: Math.min(100, root.progress) / 100 * parent.adjustedWidth + units.gu(1)
195 clip: true
128 clip: true
196
129
197− UbuntuShape {
130+ BorderImage {
198 anchors {
131 anchors {
199 left: parent.left
132 left: parent.left
200 top: parent.top
133 top: parent.top
201 bottom: parent.bottom
134 bottom: parent.bottom
202 }
135 }
203− backgroundColor: theme.palette.normal.activity
204− borderSource: "none"
205 width: progressOverlay.width
136 width: progressOverlay.width
137+ source: "graphics/progressbar-fill.sci"
206 }
138 }
207 }
139 }
208 }
140 }
209−
141+ Image {
210− Column {
211− anchors {
212− left: parent.left
213− verticalCenter: parent.verticalCenter
214− }
215− spacing: units.gu(.5)
216− Repeater {
217− objectName: "surfacePipRepeater"
218− model: Math.min(3, root.surfaceCount)
219− Rectangle {
220− objectName: "runningHighlight" + index
221− width: units.gu(0.25)
222− height: units.gu(.5)
223− color: root.alerting ? theme.palette.normal.activity : "white"
224− visible: root.itemRunning
225− }
226− }
227− }
228−
229− Rectangle {
230 objectName: "focusedHighlight"
142 objectName: "focusedHighlight"
231 anchors {
143 anchors {
232 right: parent.right
144 right: parent.right
233 verticalCenter: parent.verticalCenter
145 verticalCenter: parent.verticalCenter
234 }
146 }
235− width: units.gu(0.25)
236− height: units.gu(.5)
237− color: "white"
238 visible: root.itemFocused
147 visible: root.itemFocused
239− }
148+ source: "graphics/focused_app_arrow.png"
240−
241− UbuntuShape {
242− objectName: "shortcutHint"
243− anchors.centerIn: parent
244− width: units.gu(2.5)
245− height: width
246− backgroundColor: "#F2111111"
247− visible: root.shortcutHintShown
248− aspect: UbuntuShape.Flat
249− Label {
250− anchors.centerIn: parent
251− text: (itemIndex + 1) % 10
252− color: "white"
253− font.weight: Font.Light
254− }
255 }
149 }
256 }
150 }
257
151
@@ -270,17 +164,10 @@ Item {
270 id: shaderEffectSource
164 id: shaderEffectSource
271 sourceItem: iconItem
165 sourceItem: iconItem
272 hideSource: true
166 hideSource: true
167+ live: false
273 }
168 }
274
169
275 transform: [
170 transform: [
276− // The rotation about the icon's center/z-axis for the wiggle
277− // needs to happen here too, because there's no other way to
278− // align the wiggle with the icon-folding otherwise
279− Rotation {
280− axis { x: 0; y: 0; z: 1 }
281− origin { x: iconItem.width / 2; y: iconItem.height / 2; z: 0 }
282− angle: priv.wiggleAngle
283− },
284 // Rotating 3 times at top/bottom because that increases the perspective.
171 // Rotating 3 times at top/bottom because that increases the perspective.
285 // This is a hack, but as QML does not support real 3D coordinates
172 // This is a hack, but as QML does not support real 3D coordinates
286 // getting a higher perspective can only be done by a hack. This is the most
173 // getting a higher perspective can only be done by a hack. This is the most
Launcher/LauncherPanel.qmlnew file+578
@@ -0,0 +1,578 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItems
20+import Unity 0.1
21+import Unity.Launcher 0.1
22+import Ubuntu.Components.Popups 0.1
23+import "../Components/ListItems"
24+import "../Components/"
25+
26+Item {
27+ id: root
28+
29+ rotation: inverted ? 180 : 0
30+
31+ property var model
32+ property bool inverted: true
33+ property bool dragging: false
34+ property bool moving: launcherListView.moving || launcherListView.flicking
35+ property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed
36+ property int highlightIndex: -1
37+
38+ signal applicationSelected(string appId)
39+ signal dashItemSelected(int index)
40+
41+ BorderImage {
42+ id: background
43+ source: "graphics/launcher_bg.sci"
44+ anchors.fill: parent
45+ anchors.rightMargin: root.inverted ? 0 : -units.gu(1)
46+ anchors.leftMargin: root.inverted ? -units.gu(1) : 0
47+ rotation: root.rotation
48+ }
49+
50+ Column {
51+ id: mainColumn
52+ anchors {
53+ fill: parent
54+ }
55+
56+ MouseArea {
57+ id: dashItem
58+ width: parent.width
59+ height: units.gu(7)
60+ onClicked: root.dashItemSelected(0)
61+ z: 1
62+ Image {
63+ objectName: "dashItem"
64+ width: units.gu(5)
65+ height: width
66+ anchors.centerIn: parent
67+ source: "graphics/home.png"
68+ rotation: root.rotation
69+ }
70+ }
71+ ThinDivider {
72+ anchors {
73+ left: parent.left
74+ right: parent.right
75+ margins: -mainColumn.anchors.leftMargin
76+ }
77+ rotation: root.rotation
78+ }
79+
80+ Item {
81+ anchors.left: parent.left
82+ anchors.right: parent.right
83+ height: parent.height - dashItem.height - parent.spacing*2
84+
85+ Item {
86+ anchors.fill: parent
87+ clip: true
88+
89+ ListView {
90+ id: launcherListView
91+ objectName: "launcherListView"
92+ anchors {
93+ fill: parent
94+ topMargin: -extensionSize + units.gu(0.5)
95+ bottomMargin: -extensionSize + units.gu(1)
96+ leftMargin: units.gu(0.5)
97+ rightMargin: units.gu(0.5)
98+ }
99+ topMargin: extensionSize
100+ bottomMargin: extensionSize
101+ height: parent.height - dashItem.height - parent.spacing*2
102+ model: root.model
103+ cacheBuffer: itemHeight * 3
104+ snapMode: interactive ? ListView.SnapToItem : ListView.NoSnap
105+ highlightRangeMode: ListView.ApplyRange
106+ preferredHighlightBegin: (height - itemHeight) / 2
107+ preferredHighlightEnd: (height + itemHeight) / 2
108+ spacing: units.gu(0.5)
109+
110+ // The size of the area the ListView is extended to make sure items are not
111+ // destroyed when dragging them outside the list. This needs to be at least
112+ // itemHeight to prevent folded items from disappearing and DragArea limits
113+ // need to be smaller than this size to avoid breakage.
114+ property int extensionSize: 0
115+
116+ // Setting extensionSize after the list has been populated because it has
117+ // the potential to mess up with the intial positioning in combination
118+ // with snapping to the center of the list. This catches all the cases
119+ // where the item would be outside the list for more than itemHeight / 2.
120+ // For the rest, give it a flick to scroll to the beginning. Note that
121+ // the flicking alone isn't enough because in some cases it's not strong
122+ // enough to overcome the snapping.
123+ // https://bugreports.qt-project.org/browse/QTBUG-32251
124+ Component.onCompleted: {
125+ extensionSize = itemHeight * 3
126+ flick(0, clickFlickSpeed)
127+ }
128+
129+ // The height of the area where icons start getting folded
130+ property int foldingStartHeight: units.gu(6.5)
131+ // The height of the area where the items reach the final folding angle
132+ property int foldingStopHeight: foldingStartHeight - itemHeight - spacing
133+ property int itemWidth: units.gu(7)
134+ property int itemHeight: units.gu(6.5)
135+ property int clickFlickSpeed: units.gu(60)
136+ property int draggedIndex: dndArea.draggedIndex
137+ property real realContentY: contentY - originY + topMargin
138+ property int realItemHeight: itemHeight + spacing
139+
140+ // In case the start dragging transition is running, we need to delay the
141+ // move because the displaced transition would clash with it and cause items
142+ // to be moved to wrong places
143+ property bool draggingTransitionRunning: false
144+ property int scheduledMoveTo: -1
145+
146+ displaced: Transition {
147+ NumberAnimation { properties: "x,y"; duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing }
148+ }
149+
150+ delegate: FoldingLauncherDelegate {
151+ id: launcherDelegate
152+ objectName: "launcherDelegate" + index
153+ itemHeight: launcherListView.itemHeight
154+ itemWidth: launcherListView.itemWidth
155+ width: itemWidth
156+ height: itemHeight
157+ iconName: model.icon
158+ count: model.count
159+ progress: model.progress
160+ itemFocused: model.focused
161+ inverted: root.inverted
162+ z: -Math.abs(offset)
163+ maxAngle: 55
164+ property bool dragging: false
165+
166+ ThinDivider {
167+ id: dropIndicator
168+ objectName: "dropIndicator"
169+ anchors.centerIn: parent
170+ width: parent.width + mainColumn.anchors.leftMargin + mainColumn.anchors.rightMargin
171+ opacity: 0
172+ }
173+
174+ states: [
175+ State {
176+ name: "selected"
177+ when: dndArea.selectedItem === launcherDelegate && fakeDragItem.visible && !dragging
178+ PropertyChanges {
179+ target: launcherDelegate
180+ itemOpacity: 0
181+ }
182+ },
183+ State {
184+ name: "dragging"
185+ when: dragging
186+ PropertyChanges {
187+ target: launcherDelegate
188+ height: units.gu(1)
189+ itemOpacity: 0
190+ }
191+ PropertyChanges {
192+ target: dropIndicator
193+ opacity: 1
194+ }
195+ },
196+ State {
197+ name: "expanded"
198+ when: dndArea.draggedIndex >= 0 && (dndArea.preDragging || dndArea.dragging || dndArea.postDragging) && dndArea.draggedIndex != index
199+ PropertyChanges {
200+ target: launcherDelegate
201+ angle: 0
202+ offset: 0
203+ itemOpacity: 0.6
204+ }
205+ }
206+ ]
207+
208+ transitions: [
209+ Transition {
210+ from: ""
211+ to: "selected"
212+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.FastDuration }
213+ },
214+ Transition {
215+ from: "*"
216+ to: "expanded"
217+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.FastDuration }
218+ UbuntuNumberAnimation { properties: "angle,offset" }
219+ },
220+ Transition {
221+ from: "expanded"
222+ to: ""
223+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.BriskDuration }
224+ UbuntuNumberAnimation { properties: "angle,offset" }
225+ },
226+ Transition {
227+ id: draggingTransition
228+ from: "selected"
229+ to: "dragging"
230+ SequentialAnimation {
231+ PropertyAction { target: launcherListView; property: "draggingTransitionRunning"; value: true }
232+ ParallelAnimation {
233+ UbuntuNumberAnimation { properties: "height" }
234+ NumberAnimation { target: dropIndicator; properties: "opacity"; duration: UbuntuAnimation.FastDuration }
235+ }
236+ ScriptAction {
237+ script: {
238+ if (launcherListView.scheduledMoveTo > -1) {
239+ launcherListView.model.move(dndArea.draggedIndex, launcherListView.scheduledMoveTo)
240+ dndArea.draggedIndex = launcherListView.scheduledMoveTo
241+ launcherListView.scheduledMoveTo = -1
242+ }
243+ }
244+ }
245+ PropertyAction { target: launcherListView; property: "draggingTransitionRunning"; value: false }
246+ }
247+ },
248+ Transition {
249+ from: "dragging"
250+ to: "*"
251+ NumberAnimation { target: dropIndicator; properties: "opacity"; duration: UbuntuAnimation.FastDuration }
252+ NumberAnimation { properties: "itemOpacity"; duration: UbuntuAnimation.BriskDuration }
253+ SequentialAnimation {
254+ ScriptAction { script: if (index == launcherListView.count-1) launcherListView.flick(0, -launcherListView.clickFlickSpeed); }
255+ UbuntuNumberAnimation { properties: "height" }
256+ ScriptAction { script: if (index == launcherListView.count-1) launcherListView.flick(0, -launcherListView.clickFlickSpeed); }
257+ PropertyAction { target: dndArea; property: "postDragging"; value: false }
258+ PropertyAction { target: dndArea; property: "draggedIndex"; value: -1 }
259+ }
260+ }
261+ ]
262+ }
263+
264+ MouseArea {
265+ id: dndArea
266+ objectName: "dndArea"
267+ anchors {
268+ fill: parent
269+ topMargin: launcherListView.topMargin
270+ bottomMargin: launcherListView.bottomMargin
271+ }
272+ drag.minimumY: -launcherListView.topMargin
273+ drag.maximumY: height + launcherListView.bottomMargin
274+
275+ property int draggedIndex: -1
276+ property var selectedItem
277+ property bool preDragging: false
278+ property bool dragging: selectedItem !== undefined && selectedItem !== null && selectedItem.dragging
279+ property bool postDragging: false
280+ property int startX
281+ property int startY
282+
283+ onPressed: {
284+ selectedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY)
285+ }
286+
287+ onClicked: {
288+ var index = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
289+ var clickedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY)
290+
291+ // Check if we actually clicked an item or only at the spacing in between
292+ if (clickedItem === null) {
293+ return;
294+ }
295+
296+ // First/last item do the scrolling at more than 12 degrees
297+ if (index == 0 || index == launcherListView.count - 1) {
298+ if (clickedItem.angle > 12) {
299+ launcherListView.flick(0, -launcherListView.clickFlickSpeed);
300+ } else if (clickedItem.angle < -12) {
301+ launcherListView.flick(0, launcherListView.clickFlickSpeed);
302+ } else {
303+ root.applicationSelected(LauncherModel.get(index).appId);
304+ }
305+ return;
306+ }
307+
308+ // the rest launches apps up to an angle of 30 degrees
309+ if (clickedItem.angle > 30) {
310+ launcherListView.flick(0, -launcherListView.clickFlickSpeed);
311+ } else if (clickedItem.angle < -30) {
312+ launcherListView.flick(0, launcherListView.clickFlickSpeed);
313+ } else {
314+ root.applicationSelected(LauncherModel.get(index).appId);
315+ }
316+ }
317+
318+ onCanceled: {
319+ selectedItem = undefined;
320+ preDragging = false;
321+ postDragging = false;
322+ }
323+
324+ onReleased: {
325+ var droppedIndex = draggedIndex;
326+ if (dragging) {
327+ postDragging = true;
328+ } else {
329+ draggedIndex = -1;
330+ }
331+
332+ if (!selectedItem) {
333+ return;
334+ }
335+
336+ selectedItem.dragging = false;
337+ selectedItem = undefined;
338+ preDragging = false;
339+
340+ drag.target = undefined
341+
342+ progressiveScrollingTimer.stop();
343+ launcherListView.interactive = true;
344+ if (droppedIndex >= launcherListView.count - 2 && postDragging) {
345+ launcherListView.flick(0, -launcherListView.clickFlickSpeed);
346+ }
347+ if (droppedIndex == 0 && postDragging) {
348+ launcherListView.flick(0, launcherListView.clickFlickSpeed);
349+ }
350+ }
351+
352+ onPressAndHold: {
353+ if (Math.abs(selectedItem.angle) > 30) {
354+ return;
355+ }
356+
357+ draggedIndex = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
358+
359+ // Opening QuickList
360+ quickList.item = selectedItem;
361+ quickList.model = launcherListView.model.get(draggedIndex).quickList;
362+ quickList.appId = launcherListView.model.get(draggedIndex).appId;
363+ quickList.state = "open";
364+
365+ launcherListView.interactive = false
366+
367+ var yOffset = draggedIndex > 0 ? (mouseY + launcherListView.realContentY) % (draggedIndex * launcherListView.realItemHeight) : mouseY + launcherListView.realContentY
368+
369+ fakeDragItem.iconName = launcherListView.model.get(draggedIndex).icon
370+ fakeDragItem.x = 0
371+ fakeDragItem.y = mouseY - yOffset + launcherListView.anchors.topMargin + launcherListView.topMargin
372+ fakeDragItem.angle = selectedItem.angle * (root.inverted ? -1 : 1)
373+ fakeDragItem.offset = selectedItem.offset * (root.inverted ? -1 : 1)
374+ fakeDragItem.count = LauncherModel.get(draggedIndex).count
375+ fakeDragItem.progress = LauncherModel.get(draggedIndex).progress
376+ fakeDragItem.flatten()
377+ drag.target = fakeDragItem
378+
379+ startX = mouseX
380+ startY = mouseY
381+ }
382+
383+ onPositionChanged: {
384+ if (draggedIndex >= 0) {
385+ if (!selectedItem.dragging) {
386+ var distance = Math.max(Math.abs(mouseX - startX), Math.abs(mouseY - startY))
387+ if (!preDragging && distance > units.gu(1.5)) {
388+ preDragging = true;
389+ quickList.state = "";
390+ }
391+ if (distance > launcherListView.itemHeight) {
392+ selectedItem.dragging = true
393+ preDragging = false;
394+ }
395+ }
396+ if (!selectedItem.dragging) {
397+ return
398+ }
399+
400+ var itemCenterY = fakeDragItem.y + fakeDragItem.height / 2
401+
402+ // Move it down by the the missing size to compensate index calculation with only expanded items
403+ itemCenterY += (launcherListView.itemHeight - selectedItem.height) / 2
404+
405+ if (mouseY > launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin - launcherListView.realItemHeight) {
406+ progressiveScrollingTimer.downwards = false
407+ progressiveScrollingTimer.start()
408+ } else if (mouseY < launcherListView.realItemHeight) {
409+ progressiveScrollingTimer.downwards = true
410+ progressiveScrollingTimer.start()
411+ } else {
412+ progressiveScrollingTimer.stop()
413+ }
414+
415+ var newIndex = (itemCenterY + launcherListView.realContentY) / launcherListView.realItemHeight
416+
417+ if (newIndex > draggedIndex + 1) {
418+ newIndex = draggedIndex + 1
419+ } else if (newIndex < draggedIndex) {
420+ newIndex = draggedIndex -1
421+ } else {
422+ return
423+ }
424+
425+ if (newIndex >= 0 && newIndex < launcherListView.count) {
426+ if (launcherListView.draggingTransitionRunning) {
427+ launcherListView.scheduledMoveTo = newIndex
428+ } else {
429+ launcherListView.model.move(draggedIndex, newIndex)
430+ draggedIndex = newIndex
431+ }
432+ }
433+ }
434+ }
435+ }
436+ Timer {
437+ id: progressiveScrollingTimer
438+ interval: 2
439+ repeat: true
440+ running: false
441+ property bool downwards: true
442+ onTriggered: {
443+ if (downwards) {
444+ var minY = -launcherListView.topMargin
445+ if (launcherListView.contentY > minY) {
446+ launcherListView.contentY = Math.max(launcherListView.contentY - units.dp(2), minY)
447+ }
448+ } else {
449+ var maxY = launcherListView.contentHeight - launcherListView.height + launcherListView.topMargin + launcherListView.originY
450+ if (launcherListView.contentY < maxY) {
451+ launcherListView.contentY = Math.min(launcherListView.contentY + units.dp(2), maxY)
452+ }
453+ }
454+ }
455+ }
456+ }
457+ }
458+
459+ LauncherDelegate {
460+ id: fakeDragItem
461+ objectName: "fakeDragItem"
462+ visible: dndArea.draggedIndex >= 0 && !dndArea.postDragging
463+ itemWidth: launcherListView.itemWidth
464+ itemHeight: launcherListView.itemHeight
465+ height: itemHeight
466+ width: itemWidth
467+ rotation: root.rotation
468+ itemOpacity: 0.9
469+
470+ function flatten() {
471+ fakeDragItemAnimation.start();
472+ }
473+
474+ UbuntuNumberAnimation {
475+ id: fakeDragItemAnimation
476+ target: fakeDragItem;
477+ properties: "angle,offset";
478+ to: 0
479+ }
480+ }
481+ }
482+ }
483+
484+ UbuntuShapeForItem {
485+ id: quickListShape
486+ objectName: "quickListShape"
487+ anchors.fill: quickList
488+ opacity: quickList.state === "open" ? 0.8 : 0
489+ visible: opacity > 0
490+ rotation: root.rotation
491+
492+ Behavior on opacity {
493+ UbuntuNumberAnimation {}
494+ }
495+
496+ image: quickList
497+
498+ Image {
499+ anchors {
500+ right: parent.left
501+ rightMargin: -units.dp(4)
502+ verticalCenter: parent.verticalCenter
503+ verticalCenterOffset: -quickList.offset
504+ }
505+ height: units.gu(1)
506+ width: units.gu(2)
507+ source: "graphics/quicklist_tooltip.png"
508+ rotation: 90
509+ }
510+
511+ InverseMouseArea {
512+ anchors.fill: parent
513+ enabled: quickList.state == "open"
514+ onClicked: {
515+ quickList.state = ""
516+ }
517+ }
518+
519+ }
520+
521+ Rectangle {
522+ id: quickList
523+ objectName: "quickList"
524+ color: "#221e1c"
525+ width: units.gu(30)
526+ height: quickListColumn.height
527+ anchors {
528+ left: root.inverted ? undefined : parent.right
529+ right: root.inverted ? parent.left : undefined
530+ margins: units.gu(1)
531+
532+ }
533+ y: itemCenter - (height / 2) + offset
534+ rotation: root.rotation
535+
536+ property var model
537+ property string appId
538+ property var item
539+
540+ // internal
541+ property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)
542+ property int offset: itemCenter + (height/2) + units.gu(1) > parent.height ? -itemCenter - (height/2) - units.gu(1) + parent.height :
543+ itemCenter - (height/2) < units.gu(1) ? (height/2) - itemCenter + units.gu(1) : 0
544+
545+ Column {
546+ id: quickListColumn
547+ width: parent.width
548+ height: childrenRect.height
549+
550+ Repeater {
551+ id: popoverRepeater
552+ model: quickList.model
553+
554+ ListItems.Standard {
555+ objectName: "quickListEntry" + index
556+ text: (model.clickable ? "" : "<b>") + model.label + (model.clickable ? "" : "</b>")
557+ highlightWhenPressed: model.clickable
558+
559+ // FIXME: This is a workaround for the theme not being context sensitive. I.e. the
560+ // ListItems don't know that they are sitting in a themed Popover where the color
561+ // needs to be inverted.
562+ __foregroundColor: Theme.palette.selected.backgroundText
563+
564+ onClicked: {
565+ if (!model.clickable) {
566+ return;
567+ }
568+ quickList.state = "";
569+ // Unsetting model to prevent showing changing entries during fading out
570+ // that may happen because of triggering an action.
571+ LauncherModel.quickListActionInvoked(quickList.appId, index);
572+ quickList.model = undefined;
573+ }
574+ }
575+ }
576+ }
577+ }
578+}
Launcher/graphics/focused_app_arrow@30.pngnew file

Binary file not shown.

Launcher/graphics/highlight@18.pngnew file

Binary file not shown.

Launcher/graphics/home@18.pngnew file

Binary file not shown.

Launcher/graphics/launcher_bg@30.pngnew file

Binary file not shown.

Launcher/graphics/launcher_bg@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 4
2+border.top: 4
3+border.bottom: 4
4+border.right: 66
5+source: launcher_bg@30.png
Launcher/graphics/non-selected@18.pngnew file

Binary file not shown.

Launcher/graphics/non-selected@18.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 54
2+border.top: 60
3+border.bottom: 60
4+border.right: 54
5+source: non-selected@18.png
Launcher/graphics/notification@30.pngnew file

Binary file not shown.

Launcher/graphics/notification@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 36
2+border.top: 36
3+border.bottom: 36
4+border.right: 36
5+source: notification@30.png
Launcher/graphics/progressbar-fill@30.pngnew file

Binary file not shown.

Launcher/graphics/progressbar-fill@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 36
2+border.top: 16
3+border.bottom: 28
4+border.right: 36
5+source: progressbar-fill@30.png
Launcher/graphics/progressbar-trough@30.pngnew file

Binary file not shown.

Launcher/graphics/progressbar-trough@30.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 36
2+border.top: 16
3+border.bottom: 26
4+border.right: 36
5+source: progressbar-trough@30.png
Launcher/graphics/quicklist_tooltip@30.pngnew file

Binary file not shown.

Launcher/graphics/selected@18.pngnew file

Binary file not shown.

Launcher/graphics/selected@18.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 54
2+border.top: 60
3+border.bottom: 60
4+border.right: 54
5+source: selected@18.png
Launcher/graphics/triangle@18.pngnew file

Binary file not shown.

MouseTouchAdaptor.cppnew file+153
@@ -0,0 +1,153 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
17+ */
18+
19+#include "MouseTouchAdaptor.h"
20+
21+#include <qpa/qwindowsysteminterface.h>
22+
23+#include <QtGui/QMouseEvent>
24+#include <QtTest/QTest>
25+
26+using QTest::QTouchEventSequence;
27+
28+namespace {
29+Qt::MouseButton translateMouseButton(xcb_button_t detail)
30+{
31+ switch (detail) {
32+ case 1: return Qt::LeftButton;
33+ case 2: return Qt::MidButton;
34+ case 3: return Qt::RightButton;
35+ // Button values 4-7 are Wheel events
36+ default: return Qt::NoButton;
37+ }
38+}
39+} // end of anonymous namespace
40+
41+MouseTouchAdaptor::MouseTouchAdaptor()
42+ : m_leftButtonIsPressed(false)
43+{
44+ m_touchDevice = new QTouchDevice;
45+ m_touchDevice->setType(QTouchDevice::TouchScreen);
46+ QWindowSystemInterface::registerTouchDevice(m_touchDevice);
47+}
48+
49+bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
50+ void * message, long * /*result*/)
51+{
52+ if (eventType != "xcb_generic_event_t") {
53+ // wrong backend.
54+ qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
55+ return false;
56+ }
57+
58+ xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
59+
60+ switch (xcbEvent->response_type & ~0x80) {
61+ case XCB_BUTTON_PRESS:
62+ return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
63+ break;
64+ case XCB_BUTTON_RELEASE:
65+ return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
66+ break;
67+ case XCB_MOTION_NOTIFY:
68+ return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
69+ break;
70+ default:
71+ return false;
72+ break;
73+ };
74+}
75+
76+bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
77+{
78+ Qt::MouseButton button = translateMouseButton(pressEvent->detail);
79+
80+ // Just eat the event if it wasn't a left mouse press
81+ if (button != Qt::LeftButton)
82+ return true;
83+
84+ QPoint windowPos(pressEvent->event_x, pressEvent->event_y);
85+
86+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
87+
88+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
89+ false /* autoCommit */);
90+ touchEvent.press(0 /* touchId */, windowPos);
91+ touchEvent.commit(false /* processEvents */);
92+
93+ m_leftButtonIsPressed = true;
94+ return true;
95+}
96+
97+bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
98+{
99+ Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
100+
101+ // Just eat the event if it wasn't a left mouse release
102+ if (button != Qt::LeftButton)
103+ return true;
104+
105+ QPoint windowPos(releaseEvent->event_x, releaseEvent->event_y);
106+
107+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
108+
109+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
110+ false /* autoCommit */);
111+ touchEvent.release(0 /* touchId */, windowPos);
112+ touchEvent.commit(false /* processEvents */);
113+
114+ m_leftButtonIsPressed = false;
115+ return true;
116+}
117+
118+bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
119+{
120+ if (!m_leftButtonIsPressed) {
121+ return true;
122+ }
123+
124+ QPoint windowPos(event->event_x, event->event_y);
125+
126+ QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
127+
128+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
129+ false /* autoCommit */);
130+ touchEvent.move(0 /* touchId */, windowPos);
131+ touchEvent.commit(false /* processEvents */);
132+
133+ return true;
134+}
135+
136+QWindow *MouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
137+{
138+ QWindowList windowList = QGuiApplication::topLevelWindows();
139+ QWindow *foundWindow = nullptr;
140+
141+ int i = 0;
142+ while (!foundWindow && i < windowList.count()) {
143+ QWindow *window = windowList[i];
144+ if (window->winId() == windowId) {
145+ foundWindow = window;
146+ } else {
147+ ++i;
148+ }
149+ }
150+
151+ Q_ASSERT(foundWindow);
152+ return foundWindow;
153+}
src/MouseTouchAdaptor.h → MouseTouchAdaptor.hrenamed+8−31
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013,2015 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -21,52 +21,29 @@
21
21
22#include <QtCore/QAbstractNativeEventFilter>
22#include <QtCore/QAbstractNativeEventFilter>
23#include <QWindow>
23#include <QWindow>
24−
25#include <xcb/xcb.h>
24#include <xcb/xcb.h>
26
25
27class QMouseEvent;
26class QMouseEvent;
28class QTouchDevice;
27class QTouchDevice;
29
28
30// Transforms QMouseEvents into single-finger QTouchEvents.
29// Transforms QMouseEvents into single-finger QTouchEvents.
31−class MouseTouchAdaptor : public QObject, public QAbstractNativeEventFilter {
30+class MouseTouchAdaptor : public QAbstractNativeEventFilter {
32− Q_OBJECT
33−public:
34− virtual ~MouseTouchAdaptor();
35
31
32+public:
36− static MouseTouchAdaptor* instance();
33+ MouseTouchAdaptor();
37
34
38 // Filters mouse events and posts the equivalent QTouchEvents.
35 // Filters mouse events and posts the equivalent QTouchEvents.
39− bool nativeEventFilter(const QByteArray & eventType, void *message, long *result) override;
36+ virtual bool nativeEventFilter(const QByteArray & eventType, void *message, long *result);
40−
41− Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
42−
43− bool enabled() const;
44− void setEnabled(bool value);
45−
46−Q_SIGNALS:
47− void enabledChanged(bool value);
48
37
49private:
38private:
50− MouseTouchAdaptor();
51− void fetchXInput2Info();
52− bool xi2HandleEvent(xcb_ge_event_t *event);
53
39
54− bool handleButtonPress(WId windowId, uint32_t detail, uint32_t modifiers, int x, int y);
40+ bool handleButtonPress(xcb_button_press_event_t *pressEvent);
55− bool handleButtonRelease(WId windowId, uint32_t detail, uint32_t modifiers, int x, int y);
41+ bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
56− bool handleMotionNotify(WId windowId, uint32_t modifiers, int x, int y);
42+ bool handleMotionNotify(xcb_motion_notify_event_t *event);
57 QWindow *findQWindowWithXWindowID(WId windowId);
43 QWindow *findQWindowWithXWindowID(WId windowId);
58
44
59 QTouchDevice *m_touchDevice;
45 QTouchDevice *m_touchDevice;
60 bool m_leftButtonIsPressed;
46 bool m_leftButtonIsPressed;
61− bool m_triPressModifier;
62− bool m_quadPressModifier;
63−
64−
65− bool m_enabled;
66−
67− bool m_xi2Enabled{false};
68− int m_xi2Minor{-1};
69− int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
70};
47};
71
48
72#endif // MOUSE_TOUCH_ADAPTOR_H
49#endif // MOUSE_TOUCH_ADAPTOR_H
Notifications/Notification.qmlnew file+299
@@ -0,0 +1,299 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity.Notifications 1.0
20+import QMenuModel 0.1
21+import Utils 0.1
22+
23+UbuntuShape {
24+ id: notification
25+
26+ property alias iconSource: avatarIcon.source
27+ property alias secondaryIconSource: secondaryIcon.source
28+ property alias summary: summaryLabel.text
29+ property alias body: bodyLabel.text
30+ property var actions
31+ property var notificationId
32+ property var type
33+ property var hints
34+ property var notification
35+
36+ objectName: "background"
37+ implicitHeight: type != Notification.PlaceHolder ? contentColumn.height + contentColumn.spacing * 2 : 0
38+ color: Qt.rgba(0.132, 0.117, 0.109, 0.97)
39+ opacity: 0
40+ radius: "medium"
41+
42+ clip: true
43+ visible: type != Notification.PlaceHolder
44+
45+ UnityMenuModelPaths {
46+ id: paths
47+
48+ source: hints["x-canonical-private-menu-model"]
49+
50+ busNameHint: "busName"
51+ actionsHint: "actions"
52+ menuObjectPathHint: "menuPath"
53+ }
54+
55+ UnityMenuModel {
56+ id: unityMenuModel
57+
58+ busName: paths.busName
59+ actions: paths.actions
60+ menuObjectPath: paths.menuObjectPath
61+ }
62+
63+ Behavior on implicitHeight {
64+ id: heightBehavior
65+
66+ enabled: false
67+ UbuntuNumberAnimation {
68+ duration: UbuntuAnimation.SnapDuration
69+ }
70+ }
71+
72+ // delay enabling height behavior until the add transition is complete
73+ onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
74+
75+ MouseArea {
76+ id: interactiveArea
77+
78+ anchors.fill: contentColumn
79+ objectName: "interactiveArea"
80+ enabled: notification.type == Notification.Interactive
81+ onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
82+ }
83+
84+ Column {
85+ id: contentColumn
86+
87+ anchors {
88+ left: parent.left
89+ right: parent.right
90+ top: parent.top
91+ margins: spacing
92+ }
93+
94+ spacing: units.gu(1)
95+
96+ Row {
97+ id: topRow
98+
99+ spacing: contentColumn.spacing
100+ anchors {
101+ left: parent.left
102+ right: parent.right
103+ }
104+
105+ UbuntuShape {
106+ id: icon
107+
108+ objectName: "icon"
109+ width: units.gu(6)
110+ height: units.gu(6)
111+ visible: iconSource !== undefined && iconSource != ""
112+ image: Image {
113+ id: avatarIcon
114+
115+ fillMode: Image.PreserveAspectCrop
116+ }
117+ }
118+
119+ Image {
120+ id: secondaryIcon
121+
122+ objectName: "secondaryIcon"
123+ width: units.gu(2)
124+ height: units.gu(2)
125+ visible: source !== undefined && source != ""
126+ fillMode: Image.PreserveAspectCrop
127+ }
128+
129+ Column {
130+ id: labelColumn
131+ width: parent.width - x
132+
133+ anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
134+
135+ Label {
136+ id: summaryLabel
137+
138+ objectName: "summaryLabel"
139+ anchors {
140+ left: parent.left
141+ right: parent.right
142+ }
143+ fontSize: "medium"
144+ font.bold: true
145+ color: Theme.palette.selected.backgroundText
146+ elide: Text.ElideRight
147+ }
148+
149+ Label {
150+ id: bodyLabel
151+
152+ objectName: "bodyLabel"
153+ anchors {
154+ left: parent.left
155+ right: parent.right
156+ }
157+ visible: body != ""
158+ fontSize: "small"
159+ color: Theme.palette.selected.backgroundText
160+ opacity: 0.6
161+ wrapMode: Text.WordWrap
162+ maximumLineCount: 10
163+ elide: Text.ElideRight
164+ }
165+ }
166+ }
167+
168+ Column {
169+ objectName: "dialogListView"
170+ spacing: units.gu(2)
171+
172+ visible: count > 0
173+
174+ anchors.left: parent.left; anchors.right: parent.right
175+
176+ Repeater {
177+ model: unityMenuModel
178+
179+ NotificationMenuItemFactory {
180+ anchors.left: parent.left; anchors.right: parent.right
181+
182+ menuModel: unityMenuModel
183+ menuData: model
184+ menuIndex: index
185+ }
186+ }
187+ }
188+
189+ Item {
190+ id: buttonRow
191+
192+ objectName: "buttonRow"
193+ anchors {
194+ left: parent.left
195+ right: parent.right
196+ }
197+ visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
198+ height: units.gu(5)
199+
200+ property real buttonWidth: (width - contentColumn.spacing) / 2
201+ property bool expanded
202+
203+ Button {
204+ id: leftButton
205+
206+ objectName: "button1"
207+ width: parent.expanded ? parent.width : parent.buttonWidth
208+ anchors {
209+ top: parent.top
210+ bottom: parent.bottom
211+ }
212+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
213+ gradient: UbuntuColors.greyGradient
214+ onClicked: {
215+ if (actionRepeater.count > 2) {
216+ buttonRow.expanded = !buttonRow.expanded
217+ } else {
218+ notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
219+ }
220+ }
221+
222+ Behavior on width {
223+ UbuntuNumberAnimation {
224+ duration: UbuntuAnimation.SnapDuration
225+ }
226+ }
227+ }
228+
229+ Button {
230+ id: rightButton
231+
232+ objectName: "button0"
233+ anchors {
234+ left: leftButton.right
235+ leftMargin: contentColumn.spacing
236+ right: parent.right
237+ }
238+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
239+ anchors {
240+ top: parent.top
241+ bottom: parent.bottom
242+ }
243+ gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
244+ visible: width > 0
245+ onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
246+ }
247+ }
248+
249+ Column {
250+ objectName: "buttonColumn"
251+ spacing: contentColumn.spacing
252+ anchors {
253+ left: parent.left
254+ right: parent.right
255+ }
256+
257+ // calculate initial position before Column takes over
258+ y: buttonRow.y + buttonRow.height + contentColumn.spacing
259+
260+ visible: notification.type == Notification.SnapDecision
261+ height: buttonRow.expanded ? implicitHeight : 0
262+
263+ Repeater {
264+ id: actionRepeater
265+
266+ model: notification.actions
267+ delegate: Loader {
268+ id: loader
269+
270+ property string actionId: id
271+ property string actionLabel: label
272+
273+ anchors {
274+ left: parent.left
275+ right: parent.right
276+ }
277+
278+ Component {
279+ id: actionButton
280+
281+ Button {
282+ objectName: "button" + index
283+ anchors {
284+ left: parent.left
285+ right: parent.right
286+ }
287+
288+ text: loader.actionLabel
289+ height: units.gu(5)
290+ gradient: UbuntuColors.greyGradient
291+ onClicked: notification.notification.invokeAction(loader.actionId)
292+ }
293+ }
294+ sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
295+ }
296+ }
297+ }
298+ }
299+}
Notifications/NotificationMenuItemFactory.qmlnew file+96
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import "../Components"
23+import "../Greeter"
24+
25+Loader {
26+ id: menuFactory
27+
28+ property QtObject menuModel: null
29+ property QtObject menuData: null
30+ property int menuIndex
31+ property var notification
32+
33+ property var _map: {
34+ "com.canonical.snapdecision.textfield": textfield,
35+ "com.canonical.snapdecision.pinlock" : pinLock,
36+ }
37+
38+ sourceComponent: {
39+ if (menuData.type !== undefined) {
40+ var component = _map[menuData.type];
41+ if (component !== undefined) {
42+ return component;
43+ }
44+ }
45+ }
46+
47+ Component {
48+ id: textfield
49+
50+ Column {
51+ spacing: units.gu(2)
52+
53+ anchors.left: parent.left; anchors.right: parent.right
54+
55+ Component.onCompleted: {
56+ menuModel.loadExtendedAttributes(menuIndex, {"x-echo-mode-password": "bool"});
57+ textfield.echoMode = menuData.ext.xEchoModePassword ? TextInput.Password : TextInput.Normal
58+ }
59+
60+ Label {
61+ text: menuData.label
62+ }
63+
64+ TextField {
65+ id: textfield
66+
67+ anchors.left: parent.left; anchors.right: parent.right
68+ height: units.gu(5)
69+ onTextChanged: {
70+ menuModel.changeState(menuIndex, text);
71+ }
72+ }
73+ }
74+ }
75+
76+ Component {
77+ id: pinLock
78+ PinLockscreen {
79+ anchors.left: parent.left; anchors.right: parent.right
80+
81+ Component.onCompleted: {
82+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-pin-length': 'int'});
83+ pinLength = menuData.ext.xCanonicalPinLength;
84+ }
85+
86+ onEntered: {
87+ menuModel.changeState(menuIndex, passphrase);
88+ entryEnabled = false;
89+ }
90+
91+ onCancel: {
92+ menuModel.activate(menuIndex, false);
93+ }
94+ }
95+ }
96+}
Notifications/Notifications.qmlnew file+77
@@ -0,0 +1,77 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+ListView {
22+ id: notificationList
23+
24+ objectName: "notificationList"
25+ interactive: false
26+
27+ spacing: units.gu(.5)
28+ delegate: Notification {
29+ objectName: "notification" + index
30+ anchors {
31+ left: parent.left
32+ right: parent.right
33+ }
34+ type: model.type
35+ hints: model.hints
36+ iconSource: model.icon
37+ secondaryIconSource: model.secondaryIcon
38+ summary: model.summary
39+ body: model.body
40+ actions: model.actions
41+ notificationId: model.id
42+ notification: notificationList.model.getRaw(notificationId)
43+
44+ // make sure there's no opacity-difference between the several
45+ // elements in a notification
46+ layer.enabled: add.running || remove.running || populate.running
47+ }
48+
49+ populate: Transition {
50+ UbuntuNumberAnimation {
51+ property: "opacity"
52+ to: 1
53+ duration: UbuntuAnimation.SnapDuration
54+ }
55+ }
56+
57+ add: Transition {
58+ UbuntuNumberAnimation {
59+ property: "opacity"
60+ to: 1
61+ duration: UbuntuAnimation.SnapDuration
62+ }
63+ }
64+
65+ remove: Transition {
66+ UbuntuNumberAnimation {
67+ property: "opacity"
68+ to: 0
69+ }
70+ }
71+
72+ displaced: Transition {
73+ UbuntuNumberAnimation {
74+ properties: "x,y"
75+ }
76+ }
77+}
Panel/IndicatorItem.qmlnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
20+import "../Components"
21+
22+Item {
23+ id: indicatorItem
24+
25+ property alias widgetSource: loader.source
26+ property bool highlighted: false
27+ property bool dimmed: false
28+ property var indicatorProperties: undefined
29+ property bool indicatorVisible: loader.item ? loader.item.enabled : false
30+
31+ opacity: dimmed ? 0.4 : 1
32+ Behavior on opacity { StandardAnimation {} }
33+
34+ width: loader.item ? loader.item.width : 0
35+
36+ Loader {
37+ id: loader
38+
39+ onLoaded: {
40+ item.height = Qt.binding(function() { return indicatorItem.height; });
41+
42+ for(var pName in indicatorProperties) {
43+ if (item.hasOwnProperty(pName)) {
44+ item[pName] = indicatorProperties[pName];
45+ }
46+ }
47+ }
48+ }
49+
50+ Rectangle {
51+ color: Theme.palette.selected.foreground
52+ objectName: "highlight"
53+ height: units.dp(2)
54+ width: parent.width
55+ anchors.top: parent.bottom
56+ visible: highlighted
57+
58+ opacity: highlighted ? 1 : 0
59+ Behavior on opacity { StandardAnimation {} }
60+ }
61+}
Panel/IndicatorRow.qmlnew file+148
@@ -0,0 +1,148 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
20+import "../Components"
21+
22+Item {
23+ id: indicatorRow
24+
25+ property QtObject currentItem : null
26+ readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
27+ property alias row: row
28+ property QtObject indicatorsModel: null
29+ property var visibleIndicators: defined
30+ property int overFlowWidth: width
31+ property bool showAll: false
32+
33+ width: units.gu(40)
34+ height: units.gu(3)
35+
36+ function setDefaultItem() {
37+ // The leftmost indicator
38+ setCurrentItem(0);
39+ }
40+
41+ function setCurrentItem(index) {
42+ if (currentItemIndex !== index) {
43+ currentItem = rowRepeater.itemAt(index);
44+ }
45+ }
46+
47+ Timer {
48+ id: allVisible
49+ interval: 1000
50+
51+ onTriggered: {
52+ showAll = false;
53+ }
54+ }
55+
56+ Row {
57+ id: row
58+
59+ width: children.width
60+ height: parent.height
61+ anchors.right: parent.right
62+
63+ Repeater {
64+ id: rowRepeater
65+ objectName: "rowRepeater"
66+ model: indicatorsModel ? indicatorsModel : undefined
67+
68+ property int lastCount: 0
69+ onCountChanged: {
70+ if (lastCount < count) {
71+ showAll = true;
72+ allVisible.start();
73+ }
74+ lastCount = count;
75+ }
76+
77+ Item {
78+ id: itemWrapper
79+ height: indicatorRow.height
80+ width: indicatorItem.width
81+ visible: indicatorItem.indicatorVisible
82+ opacity: 1.0
83+ y: 0
84+ state: "standard"
85+
86+ property int ownIndex: index
87+ property alias highlighted: indicatorItem.highlighted
88+ property alias dimmed: indicatorItem.dimmed
89+
90+ property bool hidden: !showAll && !indicatorItem.highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
91+ property bool overflow: row.width - itemWrapper.x > overFlowWidth
92+
93+ IndicatorItem {
94+ id: indicatorItem
95+ height: parent.height
96+
97+ highlighted: indicatorRow.state != "initial" ? itemWrapper.ownIndex == indicatorRow.currentItemIndex : false
98+ dimmed: indicatorRow.state != "initial" ? itemWrapper.ownIndex != indicatorRow.currentItemIndex : false
99+
100+ widgetSource: model.widgetSource
101+ indicatorProperties : model.indicatorProperties
102+
103+ Component.onCompleted: {
104+ if (visibleIndicators == undefined) {
105+ visibleIndicators = {}
106+ }
107+ indicatorRow.visibleIndicators[model.identifier] = indicatorVisible;
108+ indicatorRow.visibleIndicatorsChanged();
109+ }
110+ onIndicatorVisibleChanged: {
111+ if (visibleIndicators == undefined) {
112+ visibleIndicators = {}
113+ }
114+ indicatorRow.visibleIndicators[model.identifier] = indicatorVisible;
115+ indicatorRow.visibleIndicatorsChanged();
116+
117+ if (indicatorVisible) {
118+ showAll = true;
119+ allVisible.start();
120+ }
121+ }
122+ }
123+
124+ states: [
125+ State {
126+ name: "standard"
127+ when: !hidden && !overflow
128+ },
129+ State {
130+ name: "overflow"
131+ when: hidden || overflow
132+ PropertyChanges { target: itemWrapper; opacity: 0.0 }
133+ }
134+ ]
135+
136+ transitions: [
137+ Transition {
138+ StandardAnimation {
139+ target: itemWrapper
140+ property: "opacity"
141+ duration: 300
142+ }
143+ }
144+ ]
145+ }
146+ }
147+ }
148+}
Panel/Indicators.qmlnew file+394
@@ -0,0 +1,394 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Gestures 0.1
20+import Unity.Indicators 0.1 as Indicators
21+
22+import "../Components"
23+import "../Components/ListItems"
24+import "../Components/Math.js" as MathLocal
25+
26+Showable {
27+ id: indicators
28+
29+ property real openedHeight: units.gu(71)
30+ property int panelHeight: units.gu(3)
31+ property bool pinnedMode: true //should be set true if indicators menu can cover whole screen
32+ property alias overFlowWidth: indicatorRow.overFlowWidth
33+ property alias showAll: indicatorRow.showAll
34+
35+ property int hintValue
36+ readonly property int lockThreshold: openedHeight / 2
37+ property bool fullyOpened: height == openedHeight
38+ property bool partiallyOpened: height > panelHeight && !fullyOpened
39+ property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
40+ property bool contentEnabled: true
41+ readonly property alias content: menuContent
42+
43+ // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
44+ // use its own values. Need to ask design about this.
45+ showAnimation: StandardAnimation {
46+ property: "height"
47+ duration: 350
48+ to: openedHeight
49+ easing.type: Easing.OutCubic
50+
51+ // Re-size if we've changed the openHeight while shown.
52+ onToChanged: {
53+ if (indicators.shown) {
54+ indicators.show();
55+ }
56+ }
57+ }
58+
59+ hideAnimation: StandardAnimation {
60+ property: "height"
61+ duration: 350
62+ to: panelHeight
63+ easing.type: Easing.OutCubic
64+ }
65+
66+ height: panelHeight
67+
68+ onHeightChanged: {
69+ // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
70+ var revealProgress = indicators.height - panelHeight
71+ if (!showAnimation.running && !hideAnimation.running) {
72+ if (revealProgress == 0) {
73+ indicators.state = "initial";
74+ } else if (revealProgress <= hintValue) {
75+ indicators.state = "hint";
76+ } else if (revealProgress > hintValue && revealProgress < lockThreshold) {
77+ indicators.state = "reveal";
78+ } else if (revealProgress >= lockThreshold && lockThreshold > 0) {
79+ indicators.state = "locked";
80+ }
81+ }
82+
83+ if (revealProgress == 0) {
84+ menuContent.releaseContent();
85+ }
86+ }
87+
88+ function calculateCurrentItem(xValue, useBuffer) {
89+ var rowCoordinates;
90+ var itemCoordinates;
91+ var currentItem;
92+ var distanceFromRightEdge;
93+ var bufferExceeded = false;
94+
95+ if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return;
96+
97+ /*
98+ If user drags the indicator handle bar down a distance hintValue or less, this is 0.
99+ If bar is dragged down a distance greater than or equal to lockThreshold, this is 1.
100+ Otherwise it contains the bar's location as a fraction of the distance between hintValue (is 0) and lockThreshold (is 1).
101+ */
102+ var verticalProgress =
103+ MathLocal.clamp((indicators.height - handle.height - hintValue) /
104+ (lockThreshold - hintValue), 0, 1);
105+
106+ /*
107+ Vertical velocity check. Don't change the indicator if we're moving too quickly.
108+ */
109+ var verticalSpeed = Math.abs(yVelocityCalculator.calculate());
110+ if (verticalSpeed >= 0.05 && indicatorRow.currentItem!=null) {
111+ return;
112+ }
113+
114+ /*
115+ Percentage of an indicator icon's width the user's press can stray horizontally from the
116+ focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
117+ go right a distance of half an icon's width before focus moves to the icon on the right
118+ */
119+ var maxBufferThreshold = 0.5;
120+
121+ /*
122+ To help users find the indicator of their choice while opening the indicators, we add logic to add a
123+ left/right buffer to each icon so it is harder for the focus to be moved accidentally to another icon,
124+ as the user moves their finger down, but yet allows them to switch indicator if they want.
125+ This buffer is wider the further the user's finger is from the top of the screen.
126+ */
127+ var effectiveBufferThreshold = maxBufferThreshold * verticalProgress;
128+
129+ rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
130+ // get the current delegate
131+ currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
132+ if (currentItem && currentItem != indicatorRow.currentItem ) {
133+ itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
134+ distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
135+ if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
136+ bufferExceeded = true;
137+ } else {
138+ if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
139+ bufferExceeded = true;
140+ } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
141+ bufferExceeded = true;
142+ }
143+ }
144+ if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
145+ indicatorRow.currentItem = currentItem;
146+ }
147+ } else if (!currentItem) {
148+ indicatorRow.setDefaultItem();
149+ }
150+ }
151+
152+ // eater
153+ MouseArea {
154+ anchors {
155+ top: parent.top
156+ bottom: handle.bottom
157+ left: parent.left
158+ right: parent.right
159+ }
160+ }
161+
162+ VerticalThinDivider {
163+ anchors {
164+ top: indicators.top
165+ topMargin: panelHeight
166+ bottom: handle.bottom
167+ right: indicators.left
168+ }
169+ width: units.dp(2)
170+ source: "graphics/VerticalDivider.png"
171+ }
172+
173+ MenuContent {
174+ id: menuContent
175+ objectName: "menuContent"
176+
177+ anchors {
178+ left: parent.left
179+ right: parent.right
180+ top: indicatorRow.bottom
181+ bottom: handle.top
182+ }
183+ indicatorsModel: indicatorsModel
184+ clip: !indicators.fullyOpened
185+ activeHeader: indicators.state == "hint" || indicators.state == "reveal"
186+ enabled: contentEnabled
187+ visibleIndicators: indicatorRow.visibleIndicators
188+
189+ Connections {
190+ property bool enableIndexChangeSignal: true
191+
192+ target: enableIndexChangeSignal ? indicatorRow : null
193+ onCurrentItemIndexChanged: {
194+ var oldActive = enableIndexChangeSignal;
195+ enableIndexChangeSignal = false;
196+
197+ menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex);
198+
199+ enableIndexChangeSignal = oldActive;
200+ }
201+ }
202+
203+ //small shadow gradient at bottom of menu
204+ Rectangle {
205+ anchors {
206+ left: parent.left
207+ right: parent.right
208+ bottom: parent.bottom
209+ }
210+ height: units.gu(0.5)
211+ gradient: Gradient {
212+ GradientStop { position: 0.0; color: "transparent" }
213+ GradientStop { position: 1.0; color: "black" }
214+ }
215+ opacity: 0.4
216+ }
217+ }
218+
219+ Rectangle {
220+ id: handle
221+
222+ color: menuContent.backgroundColor
223+
224+ anchors {
225+ left: parent.left
226+ right: parent.right
227+ bottom: parent.bottom
228+ }
229+ height: get_height()
230+ clip: height < handleImage.height
231+
232+ function get_height() {
233+ return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0);
234+ }
235+
236+ BorderImage {
237+ id: handleImage
238+ source: "graphics/handle.sci"
239+ height: panelHeight
240+ anchors {
241+ left: parent.left
242+ right: parent.right
243+ bottom: parent.bottom
244+ }
245+ }
246+ MouseArea { //prevent clicks passing through
247+ anchors.fill: parent
248+ }
249+ }
250+
251+ PanelBackground {
252+ anchors.fill: indicatorRow
253+ }
254+
255+ Indicators.IndicatorsModel {
256+ id: indicatorsModel
257+
258+ Component.onCompleted: load()
259+ }
260+
261+ IndicatorRow {
262+ id: indicatorRow
263+ objectName: "indicatorRow"
264+ anchors {
265+ left: parent.left
266+ right: parent.right
267+ }
268+ height: indicators.panelHeight
269+ indicatorsModel: indicatorsModel
270+ state: indicators.state
271+
272+ Connections {
273+ property bool enableIndexChangeSignal: true
274+
275+ target: enableIndexChangeSignal ? menuContent : null
276+ onCurrentMenuIndexChanged: {
277+ var oldActive = enableIndexChangeSignal;
278+ enableIndexChangeSignal = false;
279+
280+ indicatorRow.setCurrentItem(menuContent.currentMenuIndex);
281+
282+ enableIndexChangeSignal = oldActive;
283+ }
284+ }
285+ }
286+
287+ Connections {
288+ target: showAnimation
289+ onRunningChanged: {
290+ if (showAnimation.running) {
291+ indicators.state = "commit";
292+ }
293+ }
294+ }
295+
296+ Connections {
297+ target: hideAnimation
298+ onRunningChanged: {
299+ if (hideAnimation.running) {
300+ indicators.state = "initial";
301+ indicatorRow.currentItem = null;
302+ }
303+ }
304+ }
305+
306+ property var activeDragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle.dragging ? hideDragHandle : null
307+ // connections to the active drag handle
308+ Connections {
309+ target: activeDragHandle
310+ onTouchXChanged: {
311+ indicators.calculateCurrentItem(activeDragHandle.touchX, true);
312+ }
313+ onTouchSceneYChanged: {
314+ yVelocityCalculator.trackedPosition = activeDragHandle.touchSceneY;
315+ }
316+ }
317+
318+ DragHandle {
319+ id: showDragHandle
320+ anchors.bottom: parent.bottom
321+ // go beyond parent so that it stays reachable, at the top of the screen.
322+ anchors.bottomMargin: pinnedMode ? 0 : -panelHeight
323+ anchors.left: parent.left
324+ anchors.right: parent.right
325+ height: panelHeight
326+ direction: Direction.Downwards
327+ enabled: !indicators.shown && indicators.available
328+ hintDisplacement: pinnedMode ? indicators.hintValue : 0
329+ autoCompleteDragThreshold: maxTotalDragDistance / 2
330+ stretch: true
331+ maxTotalDragDistance: openedHeight - panelHeight
332+ distanceThreshold: pinnedMode ? 0 : units.gu(3)
333+
334+ onStatusChanged: {
335+ if (status === DirectionalDragArea.Recognized) {
336+ menuContent.activateContent();
337+ }
338+ }
339+ }
340+ DragHandle {
341+ id: hideDragHandle
342+ anchors.fill: handle
343+ direction: Direction.Upwards
344+ enabled: indicators.shown && indicators.available
345+ hintDisplacement: indicators.hintValue
346+ autoCompleteDragThreshold: maxTotalDragDistance / 6
347+ stretch: true
348+ maxTotalDragDistance: openedHeight - panelHeight
349+ distanceThreshold: 0
350+ }
351+
352+ AxisVelocityCalculator {
353+ id: yVelocityCalculator
354+ }
355+
356+ states: [
357+ State {
358+ name: "initial"
359+ },
360+ State {
361+ name: "hint"
362+ PropertyChanges {
363+ target: indicatorRow;
364+ y: pinnedMode ? 0 : panelHeight
365+ }
366+ StateChangeScript {
367+ script: {
368+ if (activeDragHandle) {
369+ calculateCurrentItem(activeDragHandle.touchX, false);
370+ }
371+ }
372+ }
373+ },
374+ State {
375+ name: "reveal"
376+ extend: "hint"
377+ },
378+ State {
379+ name: "locked"
380+ extend: "hint"
381+ },
382+ State {
383+ name: "commit"
384+ extend: "hint"
385+ }
386+ ]
387+ state: "initial"
388+
389+ transitions: [
390+ Transition {
391+ NumberAnimation {targets: [indicatorRow, menuContent]; property: "y"; duration: 300; easing.type: Easing.OutCubic}
392+ }
393+ ]
394+}
tests/qmltests/Notifications/Notification.qml → Panel/Indicators/DefaultIndicatorPage.qmlrenamed+6−13
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright 2013 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -14,19 +14,12 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16 * Authors:
16 * Authors:
17− * Mirco Mueller <mirco.mueller@canonical.com>
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
18 */
19
19
20−import Unity.Notifications 1.0
20+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
21
22
22−Notification {
23+Indicators.IndicatorPage {
23− nid: 0
24+ anchors.fill: parent
24− type: Notification.PlaceHolder
25− summary: ""
26− body: ""
27− icon: ""
28− secondaryIcon: ""
29− value: 0
30− rawActions: []
31− fullscreen: false
32}
25}
Panel/Indicators/DefaultIndicatorWidget.qmlnew file+103
@@ -0,0 +1,103 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+
24+Indicators.IndicatorWidget {
25+ id: indicatorWidget
26+
27+ width: itemRow.width + units.gu(0.5)
28+
29+ property alias leftLabel: itemLeftLabel.text
30+ property alias rightLabel: itemRightLabel.text
31+ property var icons: undefined
32+
33+ Row {
34+ id: itemRow
35+ objectName: "itemRow"
36+ anchors {
37+ top: parent.top
38+ bottom: parent.bottom
39+ horizontalCenter: parent.horizontalCenter
40+ }
41+ spacing: units.gu(0.5)
42+
43+ Label {
44+ id: itemLeftLabel
45+ objectName: "leftLabel"
46+ color: Theme.palette.selected.backgroundText
47+ opacity: 0.8
48+ font.family: "Ubuntu"
49+ fontSize: "medium"
50+ anchors.verticalCenter: parent.verticalCenter
51+ visible: text != ""
52+ }
53+
54+ Row {
55+ width: childrenRect.width
56+ anchors {
57+ top: parent.top
58+ bottom: parent.bottom
59+ }
60+ spacing: units.gu(0.5)
61+
62+ Repeater {
63+ model: indicatorWidget.icons
64+
65+ Image {
66+ id: itemImage
67+ objectName: "itemImage"
68+ visible: source != ""
69+ source: modelData
70+ height: indicatorWidget.iconSize
71+ width: indicatorWidget.iconSize
72+ anchors.verticalCenter: parent.verticalCenter
73+ }
74+ }
75+ }
76+
77+ Label {
78+ id: itemRightLabel
79+ objectName: "rightLabel"
80+ color: Theme.palette.selected.backgroundText
81+ opacity: 0.8
82+ font.family: "Ubuntu"
83+ fontSize: "medium"
84+ anchors.verticalCenter: parent.verticalCenter
85+ visible: text != ""
86+ }
87+ }
88+
89+ onRootActionStateChanged: {
90+ if (rootActionState == undefined) {
91+ leftLabel = "";
92+ rightLabel = "";
93+ icons = undefined;
94+ enabled = false;
95+ return;
96+ }
97+
98+ leftLabel = rootActionState.leftLabel ? rootActionState.leftLabel : "";
99+ rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : "";
100+ icons = rootActionState.icons;
101+ enabled = rootActionState.visible;
102+ }
103+}
qml/Panel/Indicators/client/IndicatorsClient.qml → Panel/Indicators/client/IndicatorsClient.qmlrenamed+6−15
@@ -17,16 +17,13 @@
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18 */
18 */
19
19
20−import QtQuick 2.4
20+import QtQuick 2.0
21−import Ubuntu.Components 1.3
21+import Ubuntu.Components 0.1
22+import Ubuntu.Components.ListItems 0.1 as ListItem
22
23
23Rectangle {
24Rectangle {
25+ color: "black"
24 id: root
26 id: root
25− color: theme.palette.normal.background
26−
27− Component.onCompleted: {
28− theme.name = "Ubuntu.Components.Themes.SuruDark"
29− }
30
27
31 PageStack {
28 PageStack {
32 id: pages
29 id: pages
@@ -36,14 +33,8 @@ Rectangle {
36 function reset() {
33 function reset() {
37 clear();
34 clear();
38 var component = Qt.createComponent("IndicatorsList.qml");
35 var component = Qt.createComponent("IndicatorsList.qml");
39− if (component.status !== Component.Ready) {
40− if (component.status === Component.Error)
41− console.error("Error: " + component.errorString());
42−
43− return;
44− }
45−
46− var page = component.createObject(pages, {"profile": indicatorProfile});
36+ var page = component.createObject(pages);
37+ console.log(component.errorString());
47 push(page);
38 push(page);
48 }
39 }
49 }
40 }
qml/Panel/Indicators/client/IndicatorsList.qml → Panel/Indicators/client/IndicatorsList.qmlrenamed+19−23
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright 2013-2016 Canonical Ltd.
2+ * Copyright 2013 Canonical Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -15,26 +15,22 @@
15 *
15 *
16 * Authors:
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Marco Trevisan <marco.trevisan@canonical.com>
19 */
18 */
20
19
21−import QtQuick 2.4
20+import QtQuick 2.0
22−import Ubuntu.Components 1.3
21+import Ubuntu.Components 0.1
22+import Ubuntu.Components.ListItems 0.1 as ListItem
23import Unity.Indicators 0.1 as Indicators
23import Unity.Indicators 0.1 as Indicators
24import "../.."
24import "../.."
25−import "../../../Components"
26
25
27Page {
26Page {
28 id: page
27 id: page
29 anchors.fill: parent
28 anchors.fill: parent
30− property string profile: ""
29+ title: "Plugin list"
31− header: PageHeader {
32− title: "Indicators List"
33− }
34
30
35 Indicators.IndicatorsModel {
31 Indicators.IndicatorsModel {
36 id: indicatorsModel
32 id: indicatorsModel
37− profile: page.profile
33+
38 Component.onCompleted: load()
34 Component.onCompleted: load()
39 }
35 }
40
36
@@ -44,24 +40,24 @@ Page {
44 anchors.fill: parent
40 anchors.fill: parent
45 model: indicatorsModel
41 model: indicatorsModel
46
42
47− delegate: ListItem {
43+ delegate: Indicators.FramedMenuItem {
44+ anchors.left: parent.left
45+ anchors.right: parent.right
48 objectName: identifier
46 objectName: identifier
49− height: menuItem.height + (divider.visible ? divider.height : 0)
50
47
51− ListItemLayout {
52− id: menuItem
53− title.text: identifier
48+ text: identifier
54− }
55
49
56 onClicked: {
50 onClicked: {
57− var new_page = Qt.createComponent("IndicatorRepresentation.qml");
51+ var new_page = Qt.createComponent("IndicatorsPage.qml");
58− if (new_page.status !== Component.Ready) {
52+ page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource});
59− if (new_page.status === Component.Error)
53+ }
60− console.error("Error: " + new_page.errorString());
54+
55+ Rectangle {
56+ id: background
61
57
62− return;
58+ anchors.fill: parent
63− }
59+ color: "#221e1c"
64− page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties });
60+ z: -1
65 }
61 }
66 }
62 }
67 }
63 }
Panel/Indicators/client/IndicatorsPage.qmlnew file+91
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
19+ */
20+
21+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import Ubuntu.Components.ListItems 0.1 as ListItem
24+
25+Page {
26+ id: page
27+
28+ title: indicatorProperties && indicatorProperties.title ? indicatorProperties.title : ""
29+ property variant indicatorProperties
30+ property string pageSource : pageLoader.source
31+
32+ anchors.fill: parent
33+
34+ ListItem.Standard {
35+ id: visualCheckItem
36+ text: "Enable Visual Representation"
37+ control: Switch {
38+ id: visualCheck
39+ checked: true
40+ }
41+ }
42+
43+ Loader {
44+ id: pageLoader
45+ objectName: "pageLoader"
46+ clip:true
47+
48+ Rectangle {
49+ anchors.fill: pageLoader
50+ color: "#221e1c" // FIXME not in palette yet
51+ }
52+
53+ anchors {
54+ top: visualCheckItem.bottom
55+ left: parent.left
56+ right: parent.right
57+ bottom: buttons.top
58+ topMargin: units.gu(2)
59+ bottomMargin: units.gu(2)
60+ }
61+ source : visualCheck.checked ? page.pageSource : "IndicatorsTree.qml"
62+
63+ onLoaded: {
64+ for(var pName in indicatorProperties) {
65+ if (item.hasOwnProperty(pName)) {
66+ item[pName] = indicatorProperties[pName];
67+ }
68+ }
69+ item.start();
70+ }
71+ }
72+
73+ Item {
74+ id: buttons
75+ anchors {
76+ left: parent.left
77+ right: parent.right
78+ bottom: parent.bottom
79+ margins: units.gu(1)
80+ }
81+ height: childrenRect.height
82+
83+ Button {
84+ anchors {
85+ left: parent.left
86+ }
87+ text: "Back"
88+ onClicked: page.pageStack.reset()
89+ }
90+ }
91+}
Panel/Indicators/client/IndicatorsTree.qmlnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dededkind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+import QMenuModel 0.1
24+import Ubuntu.Components.ListItems 0.1 as ListItem
25+
26+Page {
27+ id: page
28+ anchors.fill: parent
29+
30+ property string busName: unityModel.busName
31+ property string actionsObjectPath
32+ property var menuObjectPaths: undefined
33+ readonly property string device: "phone"
34+
35+ property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
36+
37+ function start() {
38+ }
39+
40+ UnityMenuModel {
41+ id: unityModel
42+ busName: page.busName
43+ actions: { "indicator": page.actionsObjectPath }
44+ menuObjectPath: page.deviceMenuObjectPath
45+ }
46+
47+ Indicators.RootActionState {
48+ menu: unityModel
49+ }
50+
51+ Indicators.ModelPrinter {
52+ id: printer
53+ model: unityModel
54+ }
55+
56+ Flickable {
57+ anchors.fill: parent
58+ contentHeight: all_data.height
59+ clip:true
60+ Text {
61+ id: all_data
62+ color: "white"
63+ text: printer.text
64+ }
65+ }
66+}
Panel/MenuContent.qmlnew file+168
@@ -0,0 +1,168 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
20+import Utils 0.1
21+import "../Components"
22+
23+// FIXME : We dont want to use MainView.
24+// Need a regular Item which can have tabs with local header.
25+// https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211704
26+MainView {
27+ id: content
28+
29+ property QtObject indicatorsModel: null
30+ property bool __contentActive: false
31+ readonly property int currentMenuIndex : filteredIndicators.mapToSource(tabs.selectedTabIndex)
32+ backgroundColor: "#221e1c" // FIXME not in palette yet
33+ property int contentReleaseInterval: 20000
34+ property bool activeHeader: false
35+ property alias visibleIndicators: visibleIndicatorsModel.visible
36+
37+ width: units.gu(40)
38+ height: units.gu(42)
39+
40+ function setCurrentMenuIndex(index) {
41+ var filteredIndex = filteredIndicators.mapFromSource(index)
42+
43+ if (tabs.selectedTabIndex !== filteredIndex) {
44+ if (tabs.selectedTabIndex == -1) {
45+ tabs.tabBar.animate = false;
46+ }
47+ tabs.selectedTabIndex = filteredIndex;
48+ tabs.tabBar.animate = true;
49+ }
50+ }
51+
52+ function activateContent() {
53+ contentReleaseTimer.stop();
54+ __contentActive = true;
55+ }
56+
57+ function releaseContent() {
58+ if (__contentActive) {
59+ contentReleaseTimer.restart();
60+ }
61+ }
62+
63+ onActiveHeaderChanged: {
64+ tabs.tabBar.selectionMode = activeHeader;
65+ tabs.tabBar.alwaysSelectionMode = activeHeader;
66+ }
67+
68+ SortFilterProxyModel {
69+ id: filteredIndicators
70+ model: visibleIndicatorsModel
71+ dynamicSortFilter: true
72+
73+ filterRole: Indicators.IndicatorsModelRole.IsVisible
74+ filterRegExp: RegExp("^true$")
75+ }
76+
77+ Indicators.VisibleIndicatorsModel {
78+ id: visibleIndicatorsModel
79+ model: indicatorsModel
80+ }
81+
82+ Tabs {
83+ id: tabs
84+ objectName: "tabs"
85+ anchors.fill: parent
86+ selectedTabIndex: -1
87+
88+ Repeater {
89+ id: repeater
90+ model: filteredIndicators
91+ objectName: "tabsRepeater"
92+
93+ // FIXME: This is needed because tabs dont handle repeaters well.
94+ // Due to the child ordering happening after child insertion.
95+ // QTBUG-32438
96+ onItemAdded: {
97+ parent.childrenChanged();
98+ }
99+
100+ Tab {
101+ id: tab
102+ objectName: model.identifier
103+
104+ page: Page {
105+ Loader {
106+ id: loader
107+ clip: true
108+ anchors.fill: parent
109+ source: pageSource
110+ asynchronous: true
111+
112+ readonly property bool indexActive: index >= 0 && index < menuActivator.count && menuActivator.content[index].active
113+ readonly property bool contentActive: content.__contentActive && indexActive
114+
115+ onContentActiveChanged: {
116+ if (contentActive && item) {
117+ item.start()
118+ } else if (!contentActive && item) {
119+ item.stop()
120+ }
121+ }
122+
123+ onVisibleChanged: {
124+ // Reset the indicator states
125+ if (!visible && item && item["reset"]) {
126+ item.reset()
127+ }
128+ }
129+
130+ onLoaded: {
131+ for(var pName in indicatorProperties) {
132+ if (item.hasOwnProperty(pName)) {
133+ item[pName] = indicatorProperties[pName]
134+ }
135+ }
136+ if (contentActive && tabs.visible) {
137+ item.start()
138+ }
139+ }
140+
141+ Binding {
142+ target: tab
143+ property: "title"
144+ value: loader.item && loader.item.hasOwnProperty("title") && loader.item.title !== "" ? loader.item.title : model.identifier
145+ }
146+ }
147+ }
148+ }
149+ }
150+ }
151+
152+ Timer {
153+ id: contentReleaseTimer
154+
155+ interval: contentReleaseInterval
156+ onTriggered: {
157+ content.__contentActive = false;
158+ menuActivator.clear();
159+ }
160+ }
161+
162+ Indicators.MenuContentActivator {
163+ id: menuActivator
164+ running: content.__contentActive
165+ baseIndex: content.currentMenuIndex
166+ count: indicatorsModel.count
167+ }
168+}
Panel/Panel.qmlnew file+153
@@ -0,0 +1,153 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+Item {
22+ id: root
23+ readonly property real panelHeight: units.gu(3) + units.dp(2)
24+ property real indicatorsMenuWidth: (shell.width > units.gu(60)) ? units.gu(40) : shell.width
25+ property alias indicators: indicatorsMenu
26+ property bool fullscreenMode: false
27+ property bool searchVisible: true
28+
29+ readonly property real separatorLineHeight: leftSeparatorLine.height
30+ readonly property real __panelMinusSeparatorLineHeight: panelHeight - separatorLineHeight
31+
32+ signal searchClicked
33+
34+ PanelBackground {
35+ id: panelBackground
36+ anchors {
37+ left: parent.left
38+ right: parent.right
39+ }
40+ height: __panelMinusSeparatorLineHeight
41+ y: 0
42+
43+ Behavior on y { StandardAnimation {} }
44+ }
45+
46+ PanelSeparatorLine {
47+ id: leftSeparatorLine
48+ anchors {
49+ top: panelBackground.bottom
50+ left: parent.left
51+ right: indicatorsMenu.left
52+ }
53+ saturation: 1 - indicatorsMenu.unitProgress
54+ }
55+
56+ Rectangle {
57+ id: darkenedArea
58+ property real darkenedOpacity: 0.6
59+ anchors {
60+ left: parent.left
61+ right: parent.right
62+ top: panelBackground.bottom
63+ bottom: parent.bottom
64+ }
65+ color: "black"
66+ opacity: indicatorsMenu.unitProgress * darkenedOpacity
67+ MouseArea {
68+ anchors.fill: parent
69+ enabled: indicatorsMenu.shown
70+ onClicked: if (indicatorsMenu.fullyOpened) indicatorsMenu.hide();
71+ }
72+ }
73+
74+ Indicators {
75+ id: indicatorsMenu
76+ objectName: "indicators"
77+
78+ anchors.right: parent.right
79+ y: panelBackground.y
80+ width: root.indicatorsMenuWidth
81+ shown: false
82+ hintValue: __panelMinusSeparatorLineHeight * 3
83+ panelHeight: __panelMinusSeparatorLineHeight
84+ openedHeight: parent.height + (pinnedMode ? 0 : root.panelHeight)
85+ pinnedMode: !fullscreenMode
86+ overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
87+
88+ property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
89+ }
90+
91+ PanelSeparatorLine {
92+ id: indicatorsSeparatorLine
93+ visible: true
94+ anchors {
95+ left: indicatorsMenu.left
96+ right: indicatorsMenu.right
97+ }
98+ y: indicatorsMenu.visualBottom
99+ }
100+
101+ BorderImage {
102+ id: dropShadow
103+ anchors {
104+ top: indicators.top
105+ bottom: indicatorsSeparatorLine.bottom
106+ left: indicators.left
107+ right: indicators.right
108+ margins: -units.gu(1)
109+ }
110+ visible: indicatorsMenu.height > indicatorsMenu.panelHeight
111+ source: "graphics/rectangular_dropshadow.sci"
112+ }
113+
114+ SearchIndicator {
115+ id: search
116+ objectName: "search"
117+ enabled: root.searchVisible
118+
119+ state: {
120+ if (parent.width < indicatorsMenu.width + width) {
121+ if (indicatorsMenu.state != "initial") {
122+ return "hidden";
123+ }
124+ }
125+ if (root.searchVisible && !indicatorsMenu.showAll) {
126+ return "visible";
127+ }
128+
129+ return "hidden";
130+ }
131+
132+ height: __panelMinusSeparatorLineHeight
133+ anchors {
134+ top: panelBackground.top
135+ left: panelBackground.left
136+ }
137+
138+ onClicked: root.searchClicked()
139+ }
140+
141+ states: [
142+ State {
143+ name: "in" //fully opaque and visible at top edge of screen
144+ when: !fullscreenMode
145+ PropertyChanges { target: panelBackground; y: 0 }
146+ },
147+ State {
148+ name: "out" //pushed off screen
149+ when: fullscreenMode
150+ PropertyChanges { target: panelBackground; y: -panelHeight }
151+ }
152+ ]
153+}
plugins/LightDM/IntegratedLightDM/QLightDM/SessionsModel → Panel/PanelBackground.qmlrenamed+6−2
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2016 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,4 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#include "../liblightdm/SessionsModel.h"
17+import QtQuick 2.0
18+
19+Rectangle {
20+ color: "black"
21+}
tests/plugins/Ubuntu/Gestures/touchGateExample.qml → Panel/PanelSeparatorLine.qmlrenamed+6−8
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,14 +14,12 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.4
17+import QtQuick 2.0
18−import Ubuntu.Gestures 0.1
19
18
20Rectangle {
19Rectangle {
21− width: 720; height: 720
20+ property real saturation: 1.0
22
21
23− TouchGate {
22+ // orange in HSL
24− anchors.fill: parent
23+ color: Qt.hsla(16.0/360.0, saturation * 0.83, 0.47, 1.0)
25− objectName: "touchGate"
24+ height: units.dp(2)
26− }
27}
25}
Panel/SearchIndicator.qmlnew file+82
@@ -0,0 +1,82 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Components"
20+
21+Item {
22+ id: search
23+
24+ width: container.width + units.gu(2)
25+ height: units.gu(3)
26+
27+ property string headerText: i18n.tr("Search")
28+
29+ signal clicked
30+
31+ // eater
32+ MouseArea {
33+ anchors.fill: parent
34+ onClicked: search.clicked()
35+ }
36+
37+ Row {
38+ id: container
39+ objectName: "container"
40+
41+ height: parent.height
42+ width: childrenRect.width
43+ anchors {
44+ left: parent.left
45+ leftMargin: units.gu(1)
46+ }
47+ spacing: units.gu(1)
48+
49+ Behavior on opacity { StandardAnimation { duration: 300 } }
50+
51+ Image {
52+ id: icon
53+ source: "graphics/search.png"
54+ anchors.verticalCenter: parent.verticalCenter
55+ }
56+
57+ Label {
58+ text: search.headerText
59+ color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
60+ fontSize: "small"
61+ font.capitalization: Font.AllUppercase
62+ anchors.verticalCenter: parent.verticalCenter
63+ }
64+ }
65+
66+ states: [
67+ State {
68+ name: "visible"
69+ PropertyChanges {
70+ target: container
71+ opacity: 1
72+ }
73+ },
74+ State {
75+ name: "hidden"
76+ PropertyChanges {
77+ target: container
78+ opacity: 0
79+ }
80+ }
81+ ]
82+}
Panel/graphics/Battery@18.pngnew file

Binary file not shown.

Panel/graphics/Bluetooth@18.pngnew file

Binary file not shown.

Panel/graphics/Clock@18.pngnew file

Binary file not shown.

Panel/graphics/Location@18.pngnew file

Binary file not shown.

Panel/graphics/Messages@18.pngnew file

Binary file not shown.

Panel/graphics/Network@18.pngnew file

Binary file not shown.

Panel/graphics/Sound@18.pngnew file

Binary file not shown.

Panel/graphics/Sync@18.pngnew file

Binary file not shown.

Panel/graphics/System@18.pngnew file

Binary file not shown.

Panel/graphics/Time@18.pngnew file

Binary file not shown.

Panel/graphics/VerticalDivider@18.pngnew file

Binary file not shown.

Panel/graphics/handle@12.pngnew file

Binary file not shown.

Panel/graphics/handle@12.scinew file+5
@@ -0,0 +1,5 @@
1+border.left: 0
2+border.top: 1
3+border.bottom: 0
4+border.right: 0
5+source: handle@12.png
Panel/graphics/rectangular_dropshadow@30.pngnew file

Binary file not shown.

qml/Panel/graphics/rectangular_dropshadow@30.sci → Panel/graphics/rectangular_dropshadow@30.scirenamed

The content is the same.

Panel/graphics/search@12.pngnew file

Binary file not shown.

Panel/graphics/time_and_date@18.pngnew file

Binary file not shown.

README.mddeleted−31
@@ -1,31 +0,0 @@
1−# Lomiri
2−
3−Lomiri is the operating environment for everywhere. It is able to span the gaps between touch, mouse, and keyboard; between phones, tablets, and workstations; and look good doing it.
4−
5−If you want to contribute to Lomiri on Ubuntu Touch, you've come to the right place. If you want to package Lomiri for other operating systems, you'll be better served by the main branch on the repository that we're migrating to: https://gitlab.com/ubports/core/lomiri
6−
7−Lomiri has been renamed from Unity8. Most of the software on-device in Ubuntu Touch based on Ubuntu 16.04 is still called `unity8`.
8−
9−## Where to report issues
10−
11−Issues related to the version of Lomiri that currently runs on Ubuntu Touch devices may still be reported on this repository. We will move these reports to the GitLab repository as part of our final migration.
12−
13−## Developing Lomiri on Ubuntu Touch
14−
15−This repository contains the code for Lomiri currently running on Ubuntu Touch. If you would like to modify this version of Lomiri, follow the steps below. If you would like to modify Lomiri in another operating system, check out our new repository: https://gitlab.com/ubports/core/lomiri
16−
17−Lomiri can be built and its test suite run using [`clickable`](https://clickable-ut.dev). This is a convenient method to try out most graphical changes to Lomiri without an annoying redeployment process. If you wish to test your changes on your device or make changes that are more difficult to test without real hardware, check out [Making changes and testing locally on the UBports documentation](https://docs.ubports.com/en/latest/systemdev/testing-locally.html). If not, read on.
18−
19−Before you start, [install Clickable](https://clickable-ut.dev/en/latest/install.html).
20−
21−Now, clone this repository to your computer: `git clone https://github.com/ubports/unity8.git`
22−
23−Move into this directory: `cd unity8`
24−
25−Now you can use the full suite of tools provided by this repository's [clickable.yaml](clickable.yaml). For example:
26−
27−* `clickable ide qtcreator` will open QtCreator with this repository open as a project. You can edit and build the project this way, but running the tests will be a bit difficult.
28−* `clickable build --libs --verbose` will build Lomiri in the same environment as it would receive in Ubuntu Touch.
29−* `clickable test --libs` will run the entire Lomiri test suite. This test suite includes graphical tests (which are run on a virtual, invisible desktop) and non-graphical unit tests. These tests make sure Lomiri functions as prescribed and prevents new bugs from being added. You should run them before you create a PR on this repository. This command takes about 7 minutes on an Intel i7-8550U, so plan your time accordingly and use the next two options to reduce the number of times you need to run the whole test suite...
30−* `clickable ide 'cd build/x86_64-linux-gnu/unity8/ && make tryShell'` and similar commands that replace the `Shell` with another test target defined in [tests/qmltests/CMakeLists.txt](tests/qmltests/CMakeLists.txt) allow trying out some Lomiri components in a mock environment. You can use this to try out your changes to Lomiri as you develop.
31−* `clickable ide 'cd build/x86_64-linux-gnu/unity8/ && make xvfbtestShell'` and similar commands that replace the `Shell` with another test target defined in [tests/qmltests/CMakeLists.txt](tests/qmltests/CMakeLists.txt) allow running a single TestCase. You can remove the `xvfb` part of the make target to run the test case graphically, which might help you see what is causing the test to fail.
Shell.qmlnew file+781
@@ -0,0 +1,781 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import AccountsService 0.1
19+import GSettings 1.0
20+import Unity.Application 0.1
21+import Ubuntu.Components 0.1
22+import Ubuntu.Gestures 0.1
23+import Unity.Launcher 0.1
24+import LightDM 0.1 as LightDM
25+import Powerd 0.1
26+import SessionBroadcast 0.1
27+import "Dash"
28+import "Greeter"
29+import "Launcher"
30+import "Panel"
31+import "Hud"
32+import "Components"
33+import "Components/Math.js" as MathLocal
34+import "Bottombar"
35+import "SideStage"
36+import "Notifications"
37+import Unity.Notifications 1.0 as NotificationBackend
38+
39+FocusScope {
40+ id: shell
41+
42+ // this is only here to select the width / height of the window if not running fullscreen
43+ property bool tablet: false
44+ width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
45+ height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
46+
47+ property real edgeSize: units.gu(2)
48+ property url defaultBackground: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
49+ property url background
50+ readonly property real panelHeight: panel.panelHeight
51+
52+ property bool dashShown: dash.shown
53+ property bool stageScreenshotsReady: {
54+ if (sideStage.shown) {
55+ if (mainStage.applications.count > 0) {
56+ return mainStage.usingScreenshots && sideStage.usingScreenshots;
57+ } else {
58+ return sideStage.usingScreenshots;
59+ }
60+ } else {
61+ return mainStage.usingScreenshots;
62+ }
63+ }
64+
65+ property ListModel searchHistory: SearchHistoryModel {}
66+
67+ property var applicationManager: ApplicationManagerWrapper {}
68+
69+ Binding {
70+ target: LauncherModel
71+ property: "applicationManager"
72+ value: ApplicationManager
73+ }
74+
75+ Component.onCompleted: {
76+ Theme.name = "Ubuntu.Components.Themes.SuruGradient"
77+
78+ applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
79+
80+ // FIXME: if application focused before shell starts, shell draws on top of it only.
81+ // We should detect already running applications on shell start and bring them to the front.
82+ applicationManager.unfocusCurrentApplication();
83+ }
84+
85+ readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
86+ || !!applicationManager.sideStageFocusedApplication
87+ // Used for autopilot testing.
88+ readonly property string currentFocusedAppId: ApplicationManager.focusedApplicationId
89+
90+ readonly property bool fullscreenMode: {
91+ if (greeter.shown || lockscreen.shown) {
92+ return false;
93+ } else if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
94+ return mainStage.switchingFromFullscreenToFullscreen;
95+ } else if (applicationManager.mainStageFocusedApplication) {
96+ return applicationManager.mainStageFocusedApplication.fullscreen;
97+ } else {
98+ return false;
99+ }
100+ }
101+
102+ function activateApplication(desktopFile, argument) {
103+ if (applicationManager) {
104+ // For newly started applications, as it takes them time to draw their first frame
105+ // we add a delay before we hide the animation screenshots to compensate.
106+ var addDelay = !applicationManager.getApplicationFromDesktopFile(desktopFile);
107+
108+ var application;
109+ application = applicationManager.activateApplication(desktopFile, argument);
110+ if (application == null) {
111+ return;
112+ }
113+ if (application.stage == ApplicationInfo.MainStage || !sideStage.enabled) {
114+ mainStage.activateApplication(desktopFile, addDelay);
115+ } else {
116+ sideStage.activateApplication(desktopFile, addDelay);
117+ }
118+ stages.show();
119+ }
120+ }
121+
122+ GSettings {
123+ id: backgroundSettings
124+ schema.id: "org.gnome.desktop.background"
125+ }
126+ property url gSettingsPicture: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : shell.defaultBackground
127+ onGSettingsPictureChanged: {
128+ shell.background = gSettingsPicture
129+ }
130+
131+ // This is a dummy image that is needed to determine if the picture url
132+ // in backgroundSettings points to a valid picture file.
133+ // We can't do this with the real background image because setting a
134+ // new source in onStatusChanged triggers a binding loop detection
135+ // inside Image, which causes it not to render even though a valid source
136+ // would be set. We don't mind about this image staying black and just
137+ // use it for verification to populate the source for the real
138+ // background image.
139+ Image {
140+ source: shell.background
141+ height: 0
142+ width: 0
143+ sourceSize.height: 0
144+ sourceSize.width: 0
145+ onStatusChanged: {
146+ if (status == Image.Error && source != shell.defaultBackground) {
147+ shell.background = defaultBackground
148+ }
149+ }
150+ }
151+
152+ VolumeControl {
153+ id: volumeControl
154+ }
155+
156+ Keys.onVolumeUpPressed: volumeControl.volumeUp()
157+ Keys.onVolumeDownPressed: volumeControl.volumeDown()
158+
159+ Item {
160+ id: underlay
161+ objectName: "underlay"
162+ anchors.fill: parent
163+
164+ // Whether the underlay is fully covered by opaque UI elements.
165+ property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
166+
167+ readonly property bool applicationRunning: ((mainStage.applications && mainStage.applications.count > 0)
168+ || (sideStage.applications && sideStage.applications.count > 0))
169+
170+ // Whether the user should see the topmost application surface (if there's one at all).
171+ readonly property bool applicationSurfaceShouldBeSeen: applicationRunning && !stages.fullyHidden
172+ && !mainStage.usingScreenshots // but want sideStage animating over app surface
173+
174+
175+
176+ // NB! Application surfaces are stacked behing the shell one. So they can only be seen by the user
177+ // through the translucent parts of the shell surface.
178+ visible: !fullyCovered && !applicationSurfaceShouldBeSeen
179+
180+ CrossFadeImage {
181+ id: backgroundImage
182+ objectName: "backgroundImage"
183+
184+ anchors.fill: parent
185+ source: shell.background
186+ fillMode: Image.PreserveAspectCrop
187+ }
188+
189+ Rectangle {
190+ anchors.fill: parent
191+ color: "black"
192+ opacity: dash.disappearingAnimationProgress
193+ }
194+
195+ Dash {
196+ id: dash
197+ objectName: "dash"
198+
199+ available: !greeter.shown && !lockscreen.shown
200+ hides: [stages, launcher, panel.indicators]
201+ shown: disappearingAnimationProgress !== 1.0
202+ enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
203+ // FIXME: unfocus all applications when going back to the dash
204+ onEnabledChanged: {
205+ if (enabled) {
206+ shell.applicationManager.unfocusCurrentApplication()
207+ }
208+ }
209+
210+ anchors {
211+ fill: parent
212+ topMargin: panel.panelHeight
213+ }
214+
215+ contentScale: 1.0 - 0.2 * disappearingAnimationProgress
216+ opacity: 1.0 - disappearingAnimationProgress
217+ property real disappearingAnimationProgress: {
218+ if (greeter.shown) {
219+ return greeter.showProgress;
220+ } else {
221+ return stagesOuterContainer.showProgress;
222+ }
223+ }
224+
225+ // FIXME: only necessary because stagesOuterContainer.showProgress and
226+ // greeterRevealer.animatedProgress are not animated
227+ Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
228+ }
229+ }
230+
231+ Item {
232+ id: stagesOuterContainer
233+
234+ width: parent.width
235+ height: parent.height
236+ x: launcher.progress
237+ Behavior on x {SmoothedAnimation{velocity: 600}}
238+
239+ property real showProgress:
240+ MathLocal.clamp(1 - (x + stages.x) / shell.width, 0, 1)
241+
242+ Showable {
243+ id: stages
244+ objectName: "stages"
245+
246+ x: width
247+
248+ property bool fullyShown: shown && x == 0 && parent.x == 0
249+ property bool fullyHidden: !shown && x == width
250+ available: !greeter.shown
251+ hides: [panel.indicators]
252+ shown: false
253+ opacity: 1.0
254+ showAnimation: StandardAnimation { property: "x"; duration: 350; to: 0; easing.type: Easing.OutCubic }
255+ hideAnimation: StandardAnimation { property: "x"; duration: 350; to: width; easing.type: Easing.OutCubic }
256+
257+ width: parent.width
258+ height: parent.height
259+
260+ // close the stages when no focused application remains
261+ Connections {
262+ target: shell.applicationManager
263+ onMainStageFocusedApplicationChanged: stages.closeIfNoApplications()
264+ onSideStageFocusedApplicationChanged: stages.closeIfNoApplications()
265+ ignoreUnknownSignals: true
266+ }
267+
268+ function closeIfNoApplications() {
269+ if (!shell.applicationManager.mainStageFocusedApplication
270+ && !shell.applicationManager.sideStageFocusedApplication
271+ && shell.applicationManager.mainStageApplications.count == 0
272+ && shell.applicationManager.sideStageApplications.count == 0) {
273+ stages.hide();
274+ }
275+ }
276+
277+ // show the stages when an application gets the focus
278+ Connections {
279+ target: shell.applicationManager
280+ onMainStageFocusedApplicationChanged: {
281+ if (shell.applicationManager.mainStageFocusedApplication) {
282+ mainStage.show();
283+ stages.show();
284+ }
285+ }
286+ onSideStageFocusedApplicationChanged: {
287+ if (shell.applicationManager.sideStageFocusedApplication) {
288+ sideStage.show();
289+ stages.show();
290+ }
291+ }
292+ ignoreUnknownSignals: true
293+ }
294+
295+ Stage {
296+ id: mainStage
297+
298+ anchors.fill: parent
299+ fullyShown: stages.fullyShown
300+ fullyHidden: stages.fullyHidden
301+ shouldUseScreenshots: !fullyShown
302+ rightEdgeEnabled: !sideStage.enabled
303+
304+ applicationManager: shell.applicationManager
305+ rightEdgeDraggingAreaWidth: shell.edgeSize
306+ normalApplicationY: shell.panelHeight
307+
308+ shown: true
309+ function show() {
310+ stages.show();
311+ }
312+ function hide() {
313+ }
314+
315+ // FIXME: workaround the fact that focusing a main stage application
316+ // raises its surface on top of all other surfaces including the ones
317+ // that belong to side stage applications.
318+ onFocusedApplicationChanged: {
319+ if (focusedApplication && sideStage.focusedApplication && sideStage.fullyShown) {
320+ shell.applicationManager.focusApplication(sideStage.focusedApplication);
321+ }
322+ }
323+ }
324+
325+ SideStage {
326+ id: sideStage
327+
328+ applicationManager: shell.applicationManager
329+ rightEdgeDraggingAreaWidth: shell.edgeSize
330+ normalApplicationY: shell.panelHeight
331+
332+ onShownChanged: {
333+ if (!shown && mainStage.applications.count == 0) {
334+ stages.hide();
335+ }
336+ }
337+ // FIXME: when hiding the side stage, refocus the main stage
338+ // application so that it goes in front of the side stage
339+ // application and hides it
340+ onFullyShownChanged: {
341+ if (!fullyShown && stages.fullyShown && sideStage.focusedApplication != null) {
342+ shell.applicationManager.focusApplication(mainStage.focusedApplication);
343+ }
344+ }
345+
346+ enabled: shell.width >= units.gu(60)
347+ visible: enabled
348+ fullyShown: stages.fullyShown && shown
349+ && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
350+ shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
351+
352+ available: !greeter.shown && !lockscreen.shown && enabled
353+ hides: [launcher, panel.indicators]
354+ shown: false
355+ showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
356+ hideAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.closedValue; easing.type: Easing.OutQuint }
357+
358+ width: units.gu(40)
359+ height: stages.height
360+ handleExpanded: sideStageRevealer.pressed
361+ }
362+
363+ Revealer {
364+ id: sideStageRevealer
365+
366+ enabled: mainStage.applications.count > 0 && sideStage.applications.count > 0
367+ && sideStage.available
368+ direction: Qt.RightToLeft
369+ openedValue: parent.width - sideStage.width
370+ hintDisplacement: units.gu(3)
371+ /* The size of the sidestage handle needs to be bigger than the
372+ typical size used for edge detection otherwise it is really
373+ hard to grab.
374+ */
375+ handleSize: sideStage.shown ? units.gu(4) : shell.edgeSize
376+ closedValue: parent.width + sideStage.handleSizeCollapsed
377+ target: sideStage
378+ x: parent.width - width
379+ width: sideStage.width + handleSize * 0.7
380+ height: sideStage.height
381+ orientation: Qt.Horizontal
382+ }
383+
384+ DragHandle {
385+ id: stagesDragHandle
386+
387+ anchors.top: parent.top
388+ anchors.bottom: parent.bottom
389+ anchors.right: parent.left
390+
391+ width: shell.edgeSize
392+ direction: Direction.Leftwards
393+ enabled: greeter.showProgress == 0 && edgeDemo.dashEnabled
394+ property bool haveApps: mainStage.applications.count > 0 || sideStage.applications.count > 0
395+
396+ maxTotalDragDistance: haveApps ? parent.width : parent.width * 0.7
397+ // Make autocompletion impossible when !haveApps
398+ edgeDragEvaluator.minDragDistance: haveApps ? maxTotalDragDistance * 0.1 : Number.MAX_VALUE
399+ }
400+ }
401+ }
402+
403+ Lockscreen {
404+ id: lockscreen
405+ hides: [launcher, panel.indicators, hud]
406+ shown: false
407+ enabled: true
408+ showAnimation: StandardAnimation { property: "opacity"; to: 1 }
409+ hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
410+ y: panel.panelHeight
411+ x: required ? 0 : - width
412+ width: parent.width
413+ height: parent.height - panel.panelHeight
414+ background: shell.background
415+
416+ onUnlocked: lockscreen.hide()
417+ onCancel: greeter.show()
418+
419+ Component.onCompleted: {
420+ if (LightDM.Users.count == 1) {
421+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
422+ greeter.selected(0)
423+ }
424+ }
425+ }
426+
427+ Connections {
428+ target: LightDM.Greeter
429+
430+ onShowPrompt: {
431+ if (LightDM.Users.count == 1) {
432+ // TODO: There's no better way for now to determine if its a PIN or a passphrase.
433+ if (text == "PIN") {
434+ lockscreen.alphaNumeric = false
435+ } else {
436+ lockscreen.alphaNumeric = true
437+ }
438+ lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
439+ lockscreen.show();
440+ }
441+ }
442+ }
443+
444+ Greeter {
445+ id: greeter
446+ objectName: "greeter"
447+
448+ available: true
449+ hides: [launcher, panel.indicators, hud]
450+ shown: true
451+
452+ defaultBackground: shell.background
453+
454+ y: panel.panelHeight
455+ width: parent.width
456+ height: parent.height - panel.panelHeight
457+
458+ dragHandleWidth: shell.edgeSize
459+
460+ property var previousMainApp: null
461+ property var previousSideApp: null
462+
463+ function removeApplicationFocus() {
464+ greeter.previousMainApp = applicationManager.mainStageFocusedApplication;
465+ greeter.previousSideApp = applicationManager.sideStageFocusedApplication;
466+ applicationManager.unfocusCurrentApplication();
467+ }
468+
469+ function restoreApplicationFocus() {
470+ if (greeter.previousMainApp) {
471+ applicationManager.focusApplication(greeter.previousMainApp);
472+ greeter.previousMainApp = null;
473+ }
474+ if (greeter.previousSideApp) {
475+ applicationManager.focusApplication(greeter.previousSideApp);
476+ greeter.previousSideApp = null;
477+ }
478+ }
479+
480+ onShownChanged: {
481+ if (shown) {
482+ lockscreen.reset();
483+ // If there is only one user, we start authenticating with that one here.
484+ // If there are more users, the Greeter will handle that
485+ if (LightDM.Users.count == 1) {
486+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
487+ greeter.selected(0);
488+ }
489+ greeter.forceActiveFocus();
490+ removeApplicationFocus();
491+ } else {
492+ restoreApplicationFocus();
493+ }
494+ }
495+
496+ onUnlocked: greeter.hide()
497+ onSelected: {
498+ // Update launcher items for new user
499+ var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
500+ AccountsService.user = user;
501+ LauncherModel.setUser(user);
502+ }
503+
504+ onLeftTeaserPressedChanged: {
505+ if (leftTeaserPressed) {
506+ launcher.tease();
507+ }
508+ }
509+
510+ Connections {
511+ target: applicationManager
512+ ignoreUnknownSignals: true
513+ // If any app is focused when greeter is open, it's due to a user action
514+ // like a snap decision (say, an incoming call).
515+ // TODO: these should be protected to only unlock for certain applications / certain usecases
516+ // potentially only in connection with a notification.
517+ onMainStageFocusedApplicationChanged: {
518+ if (greeter.shown && applicationManager.mainStageFocusedApplication) {
519+ greeter.previousMainApp = null // make way for new focused app
520+ greeter.previousSideApp = null
521+ greeter.hide()
522+ }
523+ }
524+ onSideStageFocusedApplicationChanged: {
525+ if (greeter.shown && applicationManager.sideStageFocusedApplication) {
526+ greeter.previousMainApp = null // make way for new focused app
527+ greeter.previousSideApp = null
528+ greeter.hide()
529+ }
530+ }
531+ }
532+ }
533+
534+ InputFilterArea {
535+ anchors.fill: parent
536+ blockInput: !applicationFocused || greeter.shown || lockscreen.shown || launcher.shown
537+ || panel.indicators.shown || hud.shown
538+ }
539+
540+ Connections {
541+ id: powerConnection
542+ target: Powerd
543+
544+ onDisplayPowerStateChange: {
545+ // We ignore any display-off signals when the proximity sensor
546+ // is active. This usually indicates something like a phone call.
547+ if (status == Powerd.Off && (flags & Powerd.UseProximity) == 0) {
548+ greeter.showNow();
549+ }
550+
551+ // No reason to chew demo CPU when user isn't watching
552+ if (status == Powerd.Off) {
553+ edgeDemo.paused = true;
554+ } else if (status == Powerd.On) {
555+ edgeDemo.paused = false;
556+ }
557+ }
558+ }
559+
560+ function showHome() {
561+ var animate = !greeter.shown && !stages.shown
562+ greeter.hide()
563+ dash.setCurrentScope("home.scope", animate, false)
564+ stages.hide()
565+ }
566+
567+ Item {
568+ id: overlay
569+
570+ anchors.fill: parent
571+
572+ Panel {
573+ id: panel
574+ anchors.fill: parent //because this draws indicator menus
575+ indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
576+ indicators {
577+ hides: [launcher]
578+ available: edgeDemo.panelEnabled
579+ contentEnabled: edgeDemo.panelContentEnabled
580+ }
581+ fullscreenMode: shell.fullscreenMode
582+ searchVisible: !greeter.shown && !lockscreen.shown && dash.shown
583+
584+ InputFilterArea {
585+ anchors {
586+ top: parent.top
587+ left: parent.left
588+ right: parent.right
589+ }
590+ height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
591+ blockInput: true
592+ }
593+ }
594+
595+ Hud {
596+ id: hud
597+
598+ width: parent.width > units.gu(60) ? units.gu(40) : parent.width
599+ height: parent.height
600+
601+ available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown && edgeDemo.dashEnabled
602+ shown: false
603+ showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
604+ hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
605+
606+ Connections {
607+ target: shell.applicationManager
608+ onMainStageFocusedApplicationChanged: hud.hide()
609+ onSideStageFocusedApplicationChanged: hud.hide()
610+ }
611+ }
612+
613+ Revealer {
614+ id: hudRevealer
615+
616+ enabled: hud.shown
617+ width: hud.width
618+ anchors.left: hud.left
619+ height: parent.height
620+ target: hud.revealerTarget
621+ closedValue: height
622+ openedValue: 0
623+ direction: Qt.RightToLeft
624+ orientation: Qt.Vertical
625+ handleSize: hud.handleHeight
626+ onCloseClicked: target.hide()
627+ }
628+
629+ Bottombar {
630+ id: bottombar
631+ theHud: hud
632+ anchors.fill: parent
633+ enabled: hud.available
634+ applicationIsOnForeground: applicationFocused
635+ }
636+
637+ InputFilterArea {
638+ blockInput: launcher.shown
639+ anchors {
640+ top: parent.top
641+ bottom: parent.bottom
642+ left: parent.left
643+ }
644+ width: launcher.width
645+ }
646+
647+ Launcher {
648+ id: launcher
649+
650+ anchors.top: parent.top
651+ anchors.bottom: parent.bottom
652+ width: parent.width
653+ dragAreaWidth: shell.edgeSize
654+ available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
655+ onDashItemSelected: showHome()
656+ onDash: {
657+ if (stages.shown) {
658+ dash.setCurrentScope("applications.scope", true /* animate */, true /* reset */)
659+ stages.hide();
660+ launcher.hide();
661+ }
662+ }
663+ onLauncherApplicationSelected:{
664+ greeter.hide()
665+ shell.activateApplication(appId)
666+ }
667+ onShownChanged: {
668+ if (shown) {
669+ panel.indicators.hide()
670+ hud.hide()
671+ bottombar.hide()
672+ }
673+ }
674+ }
675+
676+ Notifications {
677+ id: notifications
678+
679+ model: NotificationBackend.Model
680+ anchors {
681+ top: parent.top
682+ right: parent.right
683+ bottom: parent.bottom
684+ leftMargin: units.gu(1)
685+ rightMargin: units.gu(1)
686+ topMargin: panel.panelHeight + units.gu(1)
687+ }
688+ states: [
689+ State {
690+ name: "narrow"
691+ when: overlay.width <= units.gu(60)
692+ AnchorChanges { target: notifications; anchors.left: parent.left }
693+ },
694+ State {
695+ name: "wide"
696+ when: overlay.width > units.gu(60)
697+ AnchorChanges { target: notifications; anchors.left: undefined }
698+ PropertyChanges { target: notifications; width: units.gu(38) }
699+ }
700+ ]
701+
702+ InputFilterArea {
703+ anchors { left: parent.left; right: parent.right }
704+ height: parent.contentHeight
705+ blockInput: height > 0
706+ }
707+ }
708+ }
709+
710+ focus: true
711+ onFocusChanged: if (!focus) forceActiveFocus();
712+
713+ InputFilterArea {
714+ anchors {
715+ top: parent.top
716+ bottom: parent.bottom
717+ left: parent.left
718+ }
719+ width: shell.edgeSize
720+ blockInput: true
721+ }
722+
723+ InputFilterArea {
724+ anchors {
725+ top: parent.top
726+ bottom: parent.bottom
727+ right: parent.right
728+ }
729+ width: shell.edgeSize
730+ blockInput: true
731+ }
732+
733+ Binding {
734+ target: i18n
735+ property: "domain"
736+ value: "unity8"
737+ }
738+
739+ OSKController {
740+ anchors.topMargin: panel.panelHeight
741+ anchors.fill: parent // as needs to know the geometry of the shell
742+ }
743+
744+ //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
745+ MouseArea {
746+ anchors.bottom: parent.bottom
747+ anchors.left: parent.left
748+ anchors.right: parent.right
749+ height: shell.applicationManager ? shell.applicationManager.keyboardHeight : 0
750+
751+ enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
752+ }
753+
754+ Label {
755+ anchors.centerIn: parent
756+ visible: applicationManager.fake
757+ text: "EARLY ALPHA\nNOT READY FOR USE"
758+ color: "lightgrey"
759+ opacity: 0.2
760+ font.weight: Font.Black
761+ horizontalAlignment: Text.AlignHCenter
762+ verticalAlignment: Text.AlignVCenter
763+ fontSizeMode: Text.Fit
764+ rotation: -45
765+ scale: Math.min(parent.width, parent.height) / width
766+ }
767+
768+ EdgeDemo {
769+ id: edgeDemo
770+ greeter: greeter
771+ launcher: launcher
772+ dash: dash
773+ indicators: panel.indicators
774+ underlay: underlay
775+ }
776+
777+ Connections {
778+ target: SessionBroadcast
779+ onShowHome: showHome()
780+ }
781+}
SideStage/SideStage.qmlnew file+68
@@ -0,0 +1,68 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Unity.Application 0.1
19+import Ubuntu.Components 0.1
20+import "../Components"
21+
22+Stage {
23+ id: stage
24+
25+ type: ApplicationInfo.SideStage
26+ property real handleSizeCollapsed: units.gu(2.5)
27+ property real handleSizeExpanded: units.gu(4)
28+ property bool handleExpanded
29+
30+ /* FIXME: workaround so that when a main stage app goes fullscreen
31+ the sidestage's top is not transparent. Proper fix would be to
32+ resize the side stage app.
33+ */
34+ Rectangle {
35+ id: backgroundBeneathPanel
36+ anchors {
37+ top: parent.top
38+ left: parent.left
39+ right: parent.right
40+ }
41+ height: shell.panelHeight
42+ color: background.color
43+ z: -1
44+ }
45+
46+ Rectangle {
47+ id: background
48+ anchors.fill: parent
49+ color: "#2c2924"
50+ z: -1
51+ visible: stage.usingScreenshots
52+ }
53+
54+ SidestageHandle {
55+ id: handle
56+ objectName: "sideStageHandle"
57+
58+ anchors {
59+ top: parent.top
60+ bottom: parent.bottom
61+ left: parent.left
62+ leftMargin: -width
63+ }
64+ width: handleExpanded ? handleSizeExpanded : handleSizeCollapsed
65+ Behavior on width { NumberAnimation { easing.type: Easing.OutQuart} }
66+ z: -1
67+ }
68+}
tests/mocks/Utils/EdgeBarrierSettings.qml → SideStage/SidestageHandle.qmlrenamed+5−5
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2013 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−pragma Singleton
18−import QtQuick 2.4
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19
19
20−QtObject {
20+BorderImage {
21− readonly property real pushThreshold: units.gu(8)
21+ source: "graphics/sidestage_handle.sci"
22}
22}
SideStage/graphics/sidestage_handle@20.pngnew file

Binary file not shown.

qml/Stage/graphics/sidestage_handle@20.sci → SideStage/graphics/sidestage_handle@20.scirenamed

The content is the same.

buildnew file+87
@@ -0,0 +1,87 @@
1+#!/bin/sh
2+
3+SETUP=false
4+CLEAN=false
5+NUM_JOBS=$(( `grep -c ^processor /proc/cpuinfo` + 1 ))
6+CODE_DIR=$( dirname `readlink -f $0` )
7+
8+usage() {
9+ echo "usage: build [OPTIONS] [BUILD_TYPE]\n" >&2
10+ echo "Script to build the shell. If BUILD_TYPE is not specified, it defaults to \"debug\".\n" >&2
11+ echo "OPTIONS:" >&2
12+ echo " -s, --setup Setup the build environment and branch Unity" >&2
13+ echo " -c, --clean Clean the build tree before building" >&2
14+ echo >&2
15+ exit 1
16+}
17+
18+ARGS=`getopt -n$0 -u -a --longoptions="setup,clean,help" -o "sch" -- "$@"`
19+[ $? -ne 0 ] && usage
20+eval set -- "$ARGS"
21+
22+while [ $# -gt 0 ]
23+do
24+ case "$1" in
25+ -s|--setup) SETUP=true;;
26+ -c|--clean) CLEAN=true;;
27+ -h|--help) usage;;
28+ --) shift;break;;
29+ esac
30+ shift
31+done
32+
33+[ $# -gt 1 ] && usage
34+
35+BUILD_TYPE="debug"
36+[ $# -eq 1 ] && BUILD_TYPE="$1"
37+
38+install_dependencies() {
39+ sudo apt-get update || exit 4
40+ echo "Installing Unity 8 dependencies.."
41+ sudo apt-get install devscripts \
42+ equivs \
43+ gsettings-desktop-schemas \
44+ qmenumodel-qml \
45+ qtdeclarative5-dee-plugin \
46+ qtdeclarative5-gsettings1.0 \
47+ qtdeclarative5-ubuntu-ui-toolkit-plugin \
48+ unity-notifications-impl \
49+ qtdeclarative5-xmllistmodel-plugin \
50+ ubuntu-mobile-icons \
51+ unity-scope-home \
52+ unity-lens-applications \
53+ || exit 5
54+}
55+
56+mk_build_deps() {
57+ [ ! -f unity8-build-deps*deb -o $CODE_DIR/debian/control -nt unity8-build-deps*deb ] && mk-build-deps --install --root-cmd sudo $CODE_DIR/debian/control
58+}
59+
60+if [ -f "/usr/bin/ccache" ] ; then
61+ if [ "x$CC" = "x" ]; then
62+ export CC='ccache gcc'
63+ fi
64+ if [ "x$CXX" = "x" ] ; then
65+ export CXX='ccache g++'
66+ fi
67+fi
68+
69+if [ -f "/usr/bin/ninja" ] ; then
70+ GENERATOR="-G Ninja"
71+ # Ninja does not need -j, it parallelizes automatically.
72+ BUILD_COMMAND="ninja"
73+else
74+ GENERATOR=
75+ BUILD_COMMAND="make -j$NUM_JOBS"
76+fi
77+
78+if $SETUP; then
79+ install_dependencies
80+else
81+ if $CLEAN; then rm -rf builddir; fi
82+ mkdir -p builddir
83+ cd builddir
84+ mk_build_deps
85+ cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE $CODE_DIR ${GENERATOR} || exit 6
86+ ${BUILD_COMMAND} || exit 7
87+fi
build.shdeleted−82
@@ -1,82 +0,0 @@
1−#!/bin/sh
2−
3−#
4−# Copyright (C) 2017 Canonical Ltd
5−#
6−# This program is free software: you can redistribute it and/or modify
7−# it under the terms of the GNU General Public License version 3 as
8−# published by the Free Software Foundation.
9−#
10−# This program is distributed in the hope that it will be useful,
11−# but WITHOUT ANY WARRANTY; without even the implied warranty of
12−# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13−# GNU General Public License for more details.
14−#
15−# You should have received a copy of the GNU General Public License
16−# along with this program. If not, see <http://www.gnu.org/licenses/>.
17−#
18−
19−SETUP=false
20−CLEAN=false
21−NUM_JOBS=$(( `grep -c ^processor /proc/cpuinfo` + 1 ))
22−CODE_DIR=$( dirname `readlink -f $0` )
23−
24−usage() {
25− echo "usage: build [OPTIONS] [BUILD_TYPE]\n" >&2
26− echo "Script to build the shell. If BUILD_TYPE is not specified, it defaults to \"debug\".\n" >&2
27− echo "OPTIONS:" >&2
28− echo " -c, --clean Clean the build tree before building" >&2
29− echo >&2
30− exit 1
31−}
32−
33−ARGS=`getopt -n$0 -u -a --longoptions="setup,clean,help" -o "sch" -- "$@"`
34−[ $? -ne 0 ] && usage
35−eval set -- "$ARGS"
36−
37−while [ $# -gt 0 ]
38−do
39− case "$1" in
40− -c|--clean) CLEAN=true;;
41− -h|--help) usage;;
42− --) shift;break;;
43− esac
44− shift
45−done
46−
47−[ $# -gt 1 ] && usage
48−
49−BUILD_TYPE="debug"
50−[ $# -eq 1 ] && BUILD_TYPE="$1"
51−
52−mk_build_deps() {
53− if [ ! -f control -o $CODE_DIR/debian/control -nt control ]; then
54− sed 's/\:native//g' $CODE_DIR/debian/control > control
55− mk-build-deps --install --root-cmd sudo control
56− fi
57−}
58−
59−if [ -f "/usr/bin/ccache" ] ; then
60− if [ "x$CC" = "x" ]; then
61− export CC='ccache gcc'
62− fi
63− if [ "x$CXX" = "x" ] ; then
64− export CXX='ccache g++'
65− fi
66−fi
67−
68−if [ -f "/usr/bin/ninja" ] ; then
69− GENERATOR="-G Ninja"
70− # Ninja does not need -j, it parallelizes automatically.
71− BUILD_COMMAND="ninja"
72−else
73− GENERATOR=
74− BUILD_COMMAND="make -j$NUM_JOBS"
75−fi
76−
77−if $CLEAN; then rm -rf builddir; fi
78−mkdir -p builddir
79−cd builddir
80−mk_build_deps
81−cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE $CODE_DIR ${GENERATOR} || exit 6
82−${BUILD_COMMAND} || exit 7
clickable.yamldeleted−153
@@ -1,153 +0,0 @@
1−clickable_minimum_required: '7'
2−builder: custom
3−build: echo Run \'clickable build --libs --verbose\' to build && false
4−restrict_arch: amd64
5−libraries:
6− unity8:
7− builder: cmake
8− src_dir: "${ROOT}"
9− test: make xvfballtests -j${NUM_PROCS}
10− dependencies_host:
11− - android-headers
12− - cmake
13− - cmake-extras
14− - dbus-test-runner
15− - debhelper
16− - dh-apparmor
17− - doxyqml
18− - g++:native
19− - gdb
20− - graphviz
21− - gsettings-ubuntu-schemas
22− - libandroid-properties-dev
23− - libconnectivity-qt1-dev
24− - libevdev-dev
25− - libgeonames-dev
26− - libgl1-mesa-dev
27− - libgl1-mesa-dri
28− - libgles2-mesa-dev
29− - libglib2.0-dev
30− - libgnome-desktop-3-12
31− - libgnome-desktop-3-dev
32− - libgsettings-qt-dev
33− - libhardware-dev
34− - liblightdm-qt5-3-dev
35− - libpam0g-dev
36− - libpulse-dev
37− - libqmenumodel-dev
38− - libqt5sql5-sqlite
39− - libqt5svg5-dev
40− - libqt5xmlpatterns5-dev
41− - libqtdbusmock1-dev
42− - libqtdbustest1-dev
43− - libsystemsettings-dev
44− - libubuntu-app-launch2-dev
45− - libubuntu-download-manager-common-dev
46− - libubuntugestures5-dev
47− - libubuntugestures5-private-dev
48− - libudev-dev
49− - libudm-common-dev
50− - libunity-api-dev
51− - libusermetricsoutput1-dev
52− - libx11-dev
53− - libxcb1-dev
54− - libxi-dev
55− - pkg-config
56− - python3-all:any
57− - python3-setuptools:native
58− - qml-module-qt-labs-folderlistmodel
59− - qml-module-qt-labs-settings
60− - qml-module-qtmultimedia
61− - qml-module-qtqml-statemachine
62− - qml-module-qtquick-layouts
63− - qml-module-qtquick-xmllistmodel
64− - qml-module-qtquick2
65− - qml-module-qtsysteminfo
66− - qml-module-qttest
67− - qml-module-ubuntu-components
68− - qml-module-ubuntu-layouts
69− - qml-module-ubuntu-settings-components
70− - qml-module-ubuntu-test
71− - qtbase5-dev
72− - qtbase5-dev-tools
73− - qtbase5-private-dev
74− - qtdbustest-runner
75− - qtdeclarative5-dev
76− - qtdeclarative5-dev-tools
77− - qtdeclarative5-private-dev
78− - qtdeclarative5-ubuntu-content1
79− - ttf-ubuntu-font-family
80− - ubports-wallpapers
81− - xvfb
82−dependencies_target:
83− - android-headers
84− - cmake
85− - cmake-extras
86− - dbus-test-runner
87− - debhelper
88− - dh-apparmor
89− - doxyqml
90− - g++:native
91− - gdb
92− - graphviz
93− - gsettings-ubuntu-schemas
94− - libandroid-properties-dev
95− - libconnectivity-qt1-dev
96− - libevdev-dev
97− - libgeonames-dev
98− - libgl1-mesa-dev
99− - libgl1-mesa-dri
100− - libgles2-mesa-dev
101− - libglib2.0-dev
102− - libgnome-desktop-3-12
103− - libgnome-desktop-3-dev
104− - libgsettings-qt-dev
105− - libhardware-dev
106− - liblightdm-qt5-3-dev
107− - libpam0g-dev
108− - libpulse-dev
109− - libqmenumodel-dev
110− - libqt5sql5-sqlite
111− - libqt5svg5-dev
112− - libqt5xmlpatterns5-dev
113− - libqtdbusmock1-dev
114− - libqtdbustest1-dev
115− - libsystemsettings-dev
116− - libubuntu-app-launch2-dev
117− - libubuntu-download-manager-common-dev
118− - libubuntugestures5-dev
119− - libubuntugestures5-private-dev
120− - libudev-dev
121− - libudm-common-dev
122− - libunity-api-dev
123− - libusermetricsoutput1-dev
124− - libx11-dev
125− - libxcb1-dev
126− - libxi-dev
127− - pkg-config
128− - python3-all:any
129− - python3-setuptools:native
130− - qml-module-qt-labs-folderlistmodel
131− - qml-module-qt-labs-settings
132− - qml-module-qtmultimedia
133− - qml-module-qtqml-statemachine
134− - qml-module-qtquick-layouts
135− - qml-module-qtquick-xmllistmodel
136− - qml-module-qtquick2
137− - qml-module-qtsysteminfo
138− - qml-module-qttest
139− - qml-module-ubuntu-components
140− - qml-module-ubuntu-layouts
141− - qml-module-ubuntu-settings-components
142− - qml-module-ubuntu-test
143− - qtbase5-dev
144− - qtbase5-dev-tools
145− - qtbase5-private-dev
146− - qtdbustest-runner
147− - qtdeclarative5-dev
148− - qtdeclarative5-dev-tools
149− - qtdeclarative5-private-dev
150− - qtdeclarative5-ubuntu-content1
151− - ttf-ubuntu-font-family
152− - ubports-wallpapers
153− - xvfb
cmake/modules/Plugins.cmakenew file+67
@@ -0,0 +1,67 @@
1+find_program(qmlplugindump_exe qmlplugindump)
2+
3+if(NOT qmlplugindump_exe)
4+ msg(FATAL_ERROR "Could not locate qmlplugindump.")
5+endif()
6+
7+# Creates target for copying and installing qmlfiles
8+#
9+# export_qmlfiles(plugin sub_path)
10+#
11+#
12+# Target to be created:
13+# - plugin-qmlfiles - Copies the qml files (*.qml, *.js, qmldir) into the shadow build folder.
14+
15+macro(export_qmlfiles PLUGIN PLUGIN_SUBPATH)
16+
17+ file(GLOB QMLFILES
18+ *.qml
19+ *.js
20+ qmldir
21+ )
22+
23+ # copy the qmldir file
24+ add_custom_target(${PLUGIN}-qmlfiles ALL
25+ COMMAND cp ${QMLFILES} ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}
26+ DEPENDS ${QMLFILES}
27+ )
28+
29+ # install the qmlfiles file.
30+ install(FILES ${QMLFILES}
31+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
32+ )
33+endmacro(export_qmlfiles)
34+
35+
36+# Creates target for generating the qmltypes file for a plugin and installs plugin files
37+#
38+# export_qmlplugin(plugin version sub_path [TARGETS target1 [target2 ...]])
39+#
40+# TARGETS additional install targets (eg the plugin shared object)
41+#
42+# Target to be created:
43+# - plugin-qmltypes - Generates the qmltypes file in the shadow build folder.
44+
45+macro(export_qmlplugin PLUGIN VERSION PLUGIN_SUBPATH)
46+ set(multi_value_keywords TARGETS)
47+ cmake_parse_arguments(qmlplugin "" "" "${multi_value_keywords}" ${ARGN})
48+
49+ # Only try to generate .qmltypes if not cross compiling
50+ if(NOT CMAKE_CROSSCOMPILING)
51+ # create the plugin.qmltypes file
52+ add_custom_target(${PLUGIN}-qmltypes ALL
53+ COMMAND ${qmlplugindump_exe} -notrelocatable ${PLUGIN} ${VERSION} ${CMAKE_BINARY_DIR}/plugins > ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
54+ )
55+ add_dependencies(${PLUGIN}-qmltypes ${PLUGIN}-qmlfiles ${qmlplugin_TARGETS})
56+
57+ # install the qmltypes file.
58+ install(FILES ${CMAKE_BINARY_DIR}/plugins/${PLUGIN_SUBPATH}/plugin.qmltypes
59+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
60+ )
61+ endif()
62+
63+ # install the additional targets
64+ install(TARGETS ${qmlplugin_TARGETS}
65+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/${PLUGIN_SUBPATH}
66+ )
67+endmacro(export_qmlplugin)
cmake/modules/QmlTest.cmake+101−469
@@ -1,489 +1,121 @@
1−# If you need to override the qmlscene or qmltestrunner executables,
1+# add_qml_test(path component_name [NO_ADD_TEST] [NO_TARGETS]
2−# create the corresponding executable target.
2+# [TARGETS target1 [target2 [...]]]
3−
3+# [IMPORT_PATHS import_path1 [import_path2 [...]]
4−# These functions respect the global STDOUT_LOGGER and ARTIFACTS_DIR variables.
4+# [PROPERTIES prop1 value1 [prop2 value2 [...]]])
5−
6−# You can use those with cmake_parse_arguments
7−# if you need to wrap and mangle arguments.
8−set(QMLTEST_OPTIONS ADD_TEST CACHE INTERNAL "")
9−set(QMLTEST_SINGLE ITERATIONS ARG_PREFIX CACHE INTERNAL "")
10−set(QMLTEST_MULTI ARGS ENVIRONMENT DEPENDS IMPORT_PATHS TARGETS CACHE INTERNAL "")
11−
12−# import_executables(name1 [name2 [...]]
13−# [OPTIONAL] # continue when not found
14−# )
15−#
16−# This will find the named executables and import them
17−# to an imported target of the same name.
18−
19−function(import_executables)
20− cmake_parse_arguments(QMLTEST "OPTIONAL" "" "" ${ARGN})
21−
22− foreach(NAME ${QMLTEST_UNPARSED_ARGUMENTS})
23− if(NOT TARGET ${NAME})
24− add_executable(${NAME} IMPORTED GLOBAL)
25− find_program(${NAME}_exe ${NAME})
26−
27− if(NOT QMLTEST_OPTIONAL AND NOT ${NAME}_exe)
28− message(FATAL_ERROR "Could not locate ${NAME}.")
29− elseif(NOT ${NAME}_exe)
30− message(STATUS "Could not locate ${NAME}, skipping.")
31− else()
32− set_target_properties(${NAME} PROPERTIES IMPORTED_LOCATION ${${NAME}_exe})
33− endif()
34− endif()
35− endforeach()
36−endfunction()
37−
38−
39−# add_qml_test(path component_name
40−# [...]
41−# )
42−#
43−# Add test targets for ${component_name} under ${path}. It's assumed
44−# that the test file is named ${path}/tst_${component_name}.qml.
45−#
46−# This function wraps add_manual_qml_test and add_qml_unittest,
47−# see below for available arguments.
48−
49−function(add_qml_test PATH COMPONENT_NAME)
50− cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
51− mangle_arguments()
52−
53− add_qml_unittest(${ARGV})
54− add_manual_qml_test(${ARGV})
55−endfunction()
56−
57−
58−# add_qml_test_data(path component_name
59−# [...]
60−# )
61#
5#
62−# Install file called ${component_name} (or ${component_name}.qml) under
6+# NO_ADD_TEST will prevent adding the test to the "test" target
63−# ${path}.
7+# NO_TARGETS will prevent adding the test to any targets
64−
8+# TARGETS lists the targets the test should be added to
65−function(add_qml_test_data PATH COMPONENT_NAME)
9+# IMPORT_PATHS will pass those paths to qmltestrunner as "-import" arguments
66− cmake_parse_arguments(TEST "" "DESTINATION" "" ${ARGN})
10+# PROPERTIES will be set on the target and test target. See CMake's set_target_properties()
67−
68− set(filename "${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/${COMPONENT_NAME}")
69−
70− if (IS_DIRECTORY "${filename}")
71− # As a convenience, allow specifying a directory and we will install
72− # all files in the dir. We do it this way rather than passing
73− # DIRECTORY to install() because we want to process any qml files.
74− file(GLOB subfiles RELATIVE "${filename}" "${filename}/*")
75− foreach(subfile ${subfiles})
76− add_qml_test_data("${PATH}/${COMPONENT_NAME}" "${subfile}")
77− endforeach()
78− return()
79− endif()
80−
81− if (NOT EXISTS "${filename}")
82− set(filename "${filename}.qml")
83− set(COMPONENT_NAME "${COMPONENT_NAME}.qml")
84− endif()
85−
86− if ("${filename}" MATCHES "\\.qml$")
87− file(READ "${filename}" contents)
88− string(REGEX REPLACE "(\"[./]*)/qml(/|\")" "\\1\\2" contents "${contents}")
89− # this is for (at least) cardcreatortest which pulls in an architecture-specific
90− # import into the plugins directory (which is a 'qml' once installed).
91− string(REGEX REPLACE "(import \"[./]*)/plugins(/|\")" "\\1/qml\\2" contents "${contents}")
92− set(filename "${CMAKE_CURRENT_BINARY_DIR}/${PATH}/${COMPONENT_NAME}")
93− file(WRITE "${filename}" "${contents}")
94− endif()
95−
96− if (TEST_DESTINATION)
97− set(DESTINATION "${TEST_DESTINATION}")
98− else()
99− file(RELATIVE_PATH relcurpath "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
100− set(DESTINATION "${SHELL_APP_DIR}/${relcurpath}/${PATH}")
101− endif()
102−
103− install(FILES "${filename}" DESTINATION "${DESTINATION}")
104−endfunction()
105−
106−
107−# add_qml_unittest(path component_name
108−# [...]
109−# )
110#
11#
111−# Add test targets for ${component_name} under ${path}. It's assumed
12+# Two targets will be created:
112−# that the test file is named ${path}/tst_${component_name}.qml.
13+# - testComponentName - Runs the test with qmltestrunner
14+# - tryComponentName - Runs the test with uqmlscene, for manual interaction
113#
15#
114−# This function wraps add_executable_test, see below for available arguments.
16+# To change/set a default value for the whole test suite, prior to calling add_qml_test, set:
115−
17+# qmltest_DEFAULT_NO_ADD_TEST (default: FALSE)
116−function(add_qml_unittest PATH COMPONENT_NAME)
18+# qmltest_DEFAULT_TARGETS
117− import_executables(qmltestrunner)
19+# qmltest_DEFAULT_IMPORT_PATHS
118−
20+# qmltest_DEFAULT_PROPERTIES
119− add_executable_test(${COMPONENT_NAME} qmltestrunner
21+
120− ${ARGN}
22+find_program(qmltestrunner_exe qmltestrunner)
23+
24+if(NOT qmltestrunner_exe)
25+ msg(FATAL_ERROR "Could not locate qmltestrunner.")
26+endif()
27+
28+set(qmlscene_exe ${CMAKE_BINARY_DIR}/tests/uqmlscene/uqmlscene)
29+
30+macro(add_manual_qml_test SUBPATH COMPONENT_NAME)
31+ set(options NO_ADD_TEST NO_TARGETS)
32+ set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES ENVIRONMENT)
33+
34+ cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
35+
36+ set(qmlscene_TARGET try${COMPONENT_NAME})
37+ set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
38+
39+ set(qmlscene_imports "")
40+ if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")
41+ foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})
42+ list(APPEND qmlscene_imports "-I")
43+ list(APPEND qmlscene_imports ${IMPORT_PATH})
44+ endforeach(IMPORT_PATH)
45+ elseif(NOT "${qmltest_DEFAULT_IMPORT_PATHS}" STREQUAL "")
46+ foreach(IMPORT_PATH ${qmltest_DEFAULT_IMPORT_PATHS})
47+ list(APPEND qmlscene_imports "-I")
48+ list(APPEND qmlscene_imports ${IMPORT_PATH})
49+ endforeach(IMPORT_PATH)
50+ endif()
51+
52+ set(qmlscene_command
53+ env ${qmltest_ENVIRONMENT}
121− ARGS -input ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
54+ ${qmlscene_exe} ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
55+ ${qmlscene_imports}
122 )
56 )
57+ add_custom_target(${qmlscene_TARGET} ${qmlscene_command})
123
58
124− if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml")
59+endmacro(add_manual_qml_test)
125− add_qml_test_data("${PATH}" "tst_${COMPONENT_NAME}.qml")
126− endif()
127−endfunction()
128−
129
60
130−# add_manual_qml_test(path component_name
61+macro(add_qml_test SUBPATH COMPONENT_NAME)
131−# [...]
62+ set(options NO_ADD_TEST NO_TARGETS)
132−# )
63+ set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES ENVIRONMENT)
133−#
134−# Add manual test targets for ${component_name} under ${path}. It's assumed
135−# that the test file is named ${path}/tst_${component_name}.qml.
136−#
137−# This function wraps add_manual_test, see below for available arguments.
138
64
139−function(add_manual_qml_test PATH COMPONENT_NAME)
65+ cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
140− import_executables(qmlscene)
141− cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
142
66
143− add_manual_test(${COMPONENT_NAME} qmlscene
67+ set(qmltest_TARGET test${COMPONENT_NAME})
144− ${ARGN}
68+ set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
145− ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
146− )
147
69
148− if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml")
70+ set(qmltestrunner_imports "")
149− add_qml_test_data("${PATH}" "tst_${COMPONENT_NAME}.qml")
71+ if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")
72+ foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})
73+ list(APPEND qmltestrunner_imports "-import")
74+ list(APPEND qmltestrunner_imports ${IMPORT_PATH})
75+ endforeach(IMPORT_PATH)
76+ elseif(NOT "${qmltest_DEFAULT_IMPORT_PATHS}" STREQUAL "")
77+ foreach(IMPORT_PATH ${qmltest_DEFAULT_IMPORT_PATHS})
78+ list(APPEND qmltestrunner_imports "-import")
79+ list(APPEND qmltestrunner_imports ${IMPORT_PATH})
80+ endforeach(IMPORT_PATH)
150 endif()
81 endif()
151−endfunction()
152−
153−
154−# add_executable_test(target component_name
155−# [...] # see doc for add_manual_qml_test for common arguments
156−# [ADD_TEST] # whether to add to the "test" target
157−# [ARG_PREFIX arg_prefix] # prefix logging arguments with this string
158−# [ARGS] arg1 [arg2 [...]] # pass these arguments to the test executable
159−# [TARGETS target1 [target2 [...]]] # make the listed targets depend on this test
160−# # if a corresponding xvfbtarget1, xvfbtarget2 etc. exists,
161−# # this test running under xvfb will be added as a dependency
162−# # of those targets
163−# [ITERATIONS count] # run this test as a benchmark for ${count} iterations
164−# )
165−#
166−# Logging options in the standard form of "-o filename,format"
167−# will be appended to the arguments list, prefixed with ARG_PREFIX.
168−# XUnitXML files will be stored in current binary dir.
169−#
170−# Three targets will be created:
171−# - test${component_name} - Runs the test
172−# - xvfbtest${component_name} - Runs the test under xvfb
173−# - gdbtest${component_name} - Runs the test under gdb
174−
175−function(add_executable_test COMPONENT_NAME TARGET)
176− import_executables(gdb xvfb-run OPTIONAL)
177−
178− cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
179− mangle_arguments()
180−
181− file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
182− set(file_logger -o ${CMAKE_CURRENT_BINARY_DIR}/test${COMPONENT_NAME}.xml,xunitxml)
183−
184− bake_arguments("${QMLTEST_ARG_PREFIX}" args ${iterations} ${file_logger} ${STDOUT_LOGGER})
185
82
186 set(qmltest_command
83 set(qmltest_command
187− $<TARGET_FILE:${TARGET}>
84+ env ${qmltest_ENVIRONMENT}
188− ${QMLTEST_ARGS}
85+ ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
189− ${args}
86+ ${qmltestrunner_imports}
87+ -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml
88+ -o -,txt
190 )
89 )
90+ add_custom_target(${qmltest_TARGET} ${qmltest_command})
191
91
192− add_qmltest_target(test${COMPONENT_NAME} ${TARGET}
92+ if(NOT "${qmltest_PROPERTIES}" STREQUAL "")
193− COMMAND ${qmltest_command}
93+ set_target_properties(${qmltest_TARGET} PROPERTIES ${qmltest_PROPERTIES})
194− ${depends}
94+ elseif(NOT "${qmltest_DEFAULT_PROPERTIES}" STREQUAL "")
195− ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
95+ set_target_properties(${qmltest_TARGET} PROPERTIES ${qmltest_DEFAULT_PROPERTIES})
196− ${add_test}
197− ${targets}
198− )
199−
200− if(TARGET xvfb-run)
201− add_qmltest_target(xvfbtest${COMPONENT_NAME} ${TARGET}
202− COMMAND $<TARGET_FILE:xvfb-run> --server-args "-screen 0 1024x768x24" --auto-servernum ${qmltest_command}
203− ${depends}
204− ENVIRONMENT QT_QPA_PLATFORM=xcb QML2_IMPORT_PATH=${imports} LD_PRELOAD=/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/mesa/libGL.so.1 ${QMLTEST_ENVIRONMENT}
205− TARGETS ${xvfb_targets}
206− )
207− endif()
208−
209− if(TARGET gdb)
210− add_qmltest_target(gdbtest${COMPONENT_NAME} ${TARGET}
211− COMMAND $<TARGET_FILE:gdb> -ex run -args ${qmltest_command}
212− ${depends}
213− ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
214− )
215 endif()
96 endif()
216−endfunction()
217−
218−
219−# add_manual_test(target component_name
220−# [DEPENDS target1 [target2 [...]]] # make this test depend on the specified targets
221−# [IMPORT_PATHS import_path1 [import_path2 [...]] # use these QML import paths
222−# # (they're searched first to last)
223−# [ENVIRONMENT var1=value1 [var2=value2 [...]]] # set these environment variables
224−# )
225−#
226−# Two targets will be created:
227−# - try${component_name} - Runs the test for manual interaction
228−# - gdbtry${component_name} - Runs the test under gdb
229
97
230−function(add_manual_test COMPONENT_NAME TARGET)
98+ if("${qmltest_NO_ADD_TEST}" STREQUAL FALSE AND NOT "${qmltest_DEFAULT_NO_ADD_TEST}" STREQUAL "TRUE")
231− import_executables(gdb OPTIONAL)
99+ add_test(${qmltest_TARGET} ${qmltest_command})
232
100
233− cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
101+ if(NOT "${qmltest_UNPARSED_ARGUMENTS}" STREQUAL "")
234− mangle_arguments()
102+ set_tests_properties(${qmltest_TARGET} PROPERTIES ${qmltest_PROPERTIES})
235−
103+ elseif(NOT "${qmltest_DEFAULT_PROPERTIES}" STREQUAL "")
236− bake_arguments("${QMLTEST_ARG_PREFIX}" args -qmljsdebugger=port:3768,3800)
104+ set_tests_properties(${qmltest_TARGET} PROPERTIES ${qmltest_DEFAULT_PROPERTIES})
237−
238− set(qmltry_command
239− $<TARGET_FILE:${TARGET}>
240− ${QMLTEST_ARGS}
241− ${args}
242− )
243−
244− add_qmltest_target(try${COMPONENT_NAME} ${TARGET}
245− COMMAND ${qmltry_command}
246− ${depends}
247− ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
248− )
249−
250− if(TARGET gdb)
251− add_qmltest_target(gdbtry${COMPONENT_NAME} ${TARGET}
252− COMMAND $<TARGET_FILE:gdb> -ex run -args ${qmltry_command}
253− ${depends}
254− ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
255− )
256− endif()
257−endfunction()
258−
259−
260−# add_meta_test(target)
261−#
262−# Adds a test target that will run one of our "meta" test targets, like
263−# xvfbuitests. This script will run the specified suite of tests on an
264−# installed system.
265−
266−function(add_meta_test TARGET_NAME)
267− cmake_parse_arguments(TEST "SERIAL" "" "DEPENDS" ${ARGN})
268−
269− add_custom_target(${TARGET_NAME})
270−
271− set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
272− if(TEST_SERIAL)
273− file(WRITE "${filename}" "#!/bin/sh\n\n")
274− else()
275− file(WRITE "${filename}" "#!/usr/bin/parallel --shebang --no-notice\n\n")
276− endif()
277−
278− add_meta_dependencies(${TARGET_NAME} DEPENDS ${TEST_DEPENDS})
279− # else we will write the rest of the script as we add cmake targets
280−
281− install(FILES "${filename}"
282− PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE
283− GROUP_EXECUTE GROUP_READ
284− WORLD_EXECUTE WORLD_READ
285− DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/scripts"
286− )
287−endfunction()
288−
289−
290−################### INTERNAL ####################
291−
292−function(install_test_script TARGET_NAME)
293− cmake_parse_arguments(TEST "" "" "COMMAND;ENVIRONMENT" ${ARGN})
294−
295− # Now write the above test into a shell script that we can run on an
296− # installed system.
297− set(script "#!/bin/sh\n\nset -x\n\n")
298− foreach(ONE_ENV ${TEST_ENVIRONMENT})
299− set(script "${script}export ${ONE_ENV}\n")
300− endforeach()
301− set(script "${script}export UNITY_TESTING_DATADIR=\"${CMAKE_INSTALL_PREFIX}/${SHELL_APP_DIR}\"\n")
302− set(script "${script}export UNITY_TESTING_LIBDIR=\"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\"\n")
303− set(script "${script}\n")
304− set(script "${script}XML_ARGS=\n")
305− set(script "${script}if [ -n \"\$ARTIFACTS_DIR\" ]; then\n")
306− set(script "${script} XML_ARGS=\"@XML_ARGS@\"\n")
307− set(script "${script} mkdir -p \"@XML_DIR@\"\n")
308− set(script "${script} touch \"@XML_FILE@\"\n")
309− set(script "${script}fi\n")
310− set(script "${script}\n")
311− foreach(ONE_CMD ${TEST_COMMAND})
312− set(script "${script}'${ONE_CMD}' ")
313− endforeach()
314− set(script "${script}\"\$@\"") # Allow passing arguments if desired
315−
316− set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
317−
318− # Generate script to file then read it back to resolve any generator
319− # expressions before we try to replace paths.
320− file(GENERATE
321− OUTPUT "${filename}"
322− CONTENT "${script}"
323− )
324−
325− # Do replacement at install time to save needless work and to make sure
326− # we are modifying file after generate step above (which doesn't happen
327− # immediately). We can't use a custom-defined function or macro here...
328− # So instead we use a giant ugly code block.
329−
330− # START OF CODE BLOCK --------------------------------------------------
331− install(CODE "
332− file(READ \"${filename}\" replacestr)
333−
334− # Now some replacements...
335− # tests like to write xml output to our builddir; we don't need that, but we do want them in ARTIFACTS_DIR
336− string(REGEX MATCH \"( '--parameter')? '-o'( '--parameter')? '[^']*,xunitxml' \" xmlargs \"\${replacestr}\")
337− string(REGEX REPLACE \"( '--parameter')? '-o'( '--parameter')? '[^']*,xunitxml' \" \" \\\$XML_ARGS \" replacestr \"\${replacestr}\")
338− string(REGEX REPLACE \"'[^']*/tests/\" \"'\\\$ARTIFACTS_DIR/tests/\" xmlargs \"\${xmlargs}\")
339− string(REGEX REPLACE \".*'([^']*),xunitxml'.*\" \"\\\\1\" xmlfile \"\${xmlargs}\")
340− string(REGEX REPLACE \"(.*)/[^/]*\" \"\\\\1\" xmldir \"\${xmlfile}\")
341− string(REGEX REPLACE \"'\" \"\" xmlargs \"\${xmlargs}\") # strip single quotes
342− string(REGEX REPLACE \"@XML_ARGS@\" \"\${xmlargs}\" replacestr \"\${replacestr}\")
343− string(REGEX REPLACE \"@XML_DIR@\" \"\${xmldir}\" replacestr \"\${replacestr}\")
344− string(REGEX REPLACE \"@XML_FILE@\" \"\${xmlfile}\" replacestr \"\${replacestr}\")
345− # replace build/source roots with their install paths
346− string(REPLACE \"${CMAKE_BINARY_DIR}/libs\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\" replacestr \"\${replacestr}\")
347− string(REPLACE \"${CMAKE_BINARY_DIR}/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}\" replacestr \"\${replacestr}\")
348− string(REPLACE \"${CMAKE_BINARY_DIR}/tests/libs\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/libs\" replacestr \"\${replacestr}\")
349− string(REPLACE \"${CMAKE_BINARY_DIR}/tests/mocks\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}/mocks\" replacestr \"\${replacestr}\")
350− string(REPLACE \"${CMAKE_BINARY_DIR}/tests/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/plugins\" replacestr \"\${replacestr}\")
351− string(REPLACE \"${CMAKE_BINARY_DIR}/tests/qmltests\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/qmltests\" replacestr \"\${replacestr}\")
352− string(REPLACE \"${CMAKE_BINARY_DIR}/tests/uqmlscene\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\" replacestr \"\${replacestr}\")
353− string(REPLACE \"${CMAKE_BINARY_DIR}/tests/utils/modules\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}/utils\" replacestr \"\${replacestr}\")
354− string(REPLACE \"${CMAKE_SOURCE_DIR}/tests/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_APP_DIR}/tests/plugins\" replacestr \"\${replacestr}\")
355− string(REPLACE \"${CMAKE_SOURCE_DIR}/tests/qmltests\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_APP_DIR}/tests/qmltests\" replacestr \"\${replacestr}\")
356−
357− file(WRITE \"${filename}\" \"\${replacestr}\")
358− ")
359− # END OF CODE BLOCK --------------------------------------------------
360−
361− install(FILES "${filename}"
362− PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE
363− GROUP_EXECUTE GROUP_READ
364− WORLD_EXECUTE WORLD_READ
365− DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/scripts"
366− )
367−endfunction()
368−
369−function(add_meta_dependencies UPSTREAM_TARGET)
370− cmake_parse_arguments(TEST "" "" "DEPENDS" ${ARGN})
371−
372− foreach(depend ${TEST_DEPENDS})
373− add_dependencies(${UPSTREAM_TARGET} ${depend})
374−
375− # add depend to the meta test script that we will install on system
376− set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${UPSTREAM_TARGET}.sh")
377− if (EXISTS "${filename}")
378− file(APPEND "${filename}" "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/scripts/${depend}.sh \"\$@\" 2>&1\n")
379 endif()
105 endif()
380− endforeach()
106+ endif("${qmltest_NO_ADD_TEST}" STREQUAL FALSE AND NOT "${qmltest_DEFAULT_NO_ADD_TEST}" STREQUAL "TRUE")
381−endfunction()
107+
382−
108+ if("${qmltest_NO_TARGETS}" STREQUAL "FALSE")
383−# add_qmltest_target(target_name target
109+ if(NOT "${qmltest_TARGETS}" STREQUAL "")
384−# COMMAND test_exe [arg1 [...]] # execute this test with arguments
110+ foreach(TARGET ${qmltest_TARGETS})
385−# [...] # see above for available arguments:
111+ add_dependencies(${TARGET} ${qmltest_TARGET})
386−# # ADD_TEST, ENVIRONMENT, DEPENDS and TARGETS
112+ endforeach(TARGET)
387−# )
113+ elseif(NOT "${qmltest_DEFAULT_TARGETS}" STREQUAL "")
388−
114+ foreach(TARGET ${qmltest_DEFAULT_TARGETS})
389−function(add_qmltest_target TARGET_NAME TARGET)
115+ add_dependencies(${TARGET} ${qmltest_TARGET})
390− cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "COMMAND;${QMLTEST_MULTI}" ${ARGN})
116+ endforeach(TARGET)
391− mangle_arguments()
392−
393− # Additional arguments
394− string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_lower)
395− if(cmake_generator_lower STREQUAL "unix makefiles")
396− set(function "$(FUNCTION)")
397− endif()
398−
399− add_custom_target(${TARGET_NAME}
400− env ${QMLTEST_ENVIRONMENT}
401− ${QMLTEST_COMMAND} ${function}
402− DEPENDS ${TARGET} ${QMLTEST_DEPENDS}
403− )
404−
405− install_test_script(${TARGET_NAME}
406− ENVIRONMENT ${QMLTEST_ENVIRONMENT}
407− COMMAND ${QMLTEST_COMMAND}
408− )
409−
410− if(QMLTEST_ADD_TEST)
411− add_test(
412− NAME ${TARGET_NAME}
413− COMMAND ${QMLTEST_COMMAND}
414− )
415−
416− foreach(ENV ${QMLTEST_ENVIRONMENT})
417− set_property(TEST ${TARGET_NAME} APPEND PROPERTY ENVIRONMENT ${ENV})
418− endforeach()
419−
420− set_property(TEST ${TARGET_NAME} APPEND PROPERTY DEPENDS ${TARGET})
421− foreach(DEPEND ${DEPENDS})
422− set_property(TEST ${TARGET_NAME} APPEND PROPERTY DEPENDS ${DEPEND})
423− endforeach()
424− endif()
425−
426− foreach(UPSTREAM_TARGET ${QMLTEST_TARGETS})
427− add_meta_dependencies(${UPSTREAM_TARGET} DEPENDS ${TARGET_NAME})
428− endforeach()
429−endfunction()
430−
431−
432−# mangle_arguments(${ARGN})
433−#
434−# Verify there were no unparsed arguments and
435−# mangle the known ones for further processing.
436−
437−macro(mangle_arguments)
438− if(QMLTEST_UNPARSED_ARGUMENTS)
439− message(FATAL_ERROR "Unexpected arguments: ${QMLTEST_UNPARSED_ARGUMENTS}")
440− endif()
441−
442− if(QMLTEST_ADD_TEST)
443− set(add_test ADD_TEST)
444− endif()
445−
446− if(QMLTEST_IMPORT_PATHS)
447− string(REPLACE ";" ":" imports "${QMLTEST_IMPORT_PATHS}")
448− endif()
449−
450− if(QMLTEST_ITERATIONS)
451− set(iterations -iterations ${QMLTEST_ITERATIONS})
452− endif()
453−
454− if(QMLTEST_DEPENDS)
455− set(depends DEPENDS ${QMLTEST_DEPENDS})
456− endif()
457−
458− if(QMLTEST_TARGETS)
459− set(targets TARGETS ${QMLTEST_TARGETS})
460− endif()
461−
462− set(xvfb_targets "")
463− foreach(target ${QMLTEST_TARGETS})
464− if(TARGET xvfb${target})
465− list(APPEND xvfb_targets xvfb${target})
466 endif()
117 endif()
467− endforeach()
118+ endif("${qmltest_NO_TARGETS}" STREQUAL "FALSE")
468− set(xvfb_targets "${xvfb_targets}" PARENT_SCOPE)
469−endmacro()
470−
471
119
472−# bake_arguments(prefix output
120+ add_manual_qml_test(${SUBPATH} ${COMPONENT_NAME} ${ARGN})
473−# arg1 [arg2 [...]]
121+endmacro(add_qml_test)
474−# )
475−#
476−# If set, add the argument prefix before every passed
477−# argument and store the result in ${OUTPUT} variable.
478−
479−function(bake_arguments PREFIX OUTPUT)
480− set(args "${ARGN}")
481− if(PREFIX)
482− set(args "")
483− foreach(arg ${ARGN})
484− list(APPEND args ${PREFIX})
485− list(APPEND args ${arg})
486− endforeach()
487− endif()
488− set(${OUTPUT} "${args}" PARENT_SCOPE)
489−endfunction()
cmake/modules/autopilot.cmake+2−7
@@ -2,15 +2,10 @@ add_custom_target(autopilot)
2
2
3function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
3function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
4 add_custom_target(autopilot-${TEST_NAME}
4 add_custom_target(autopilot-${TEST_NAME}
5− COMMAND UNITY_TESTING=1 LANG=C QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python3 -m autopilot.run run ${TEST_SUITE}
5+ COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_PRIVATE_LIBDIR}/qml/mocks autopilot run ${TEST_SUITE}
6 WORKING_DIRECTORY ${WORKING_DIR}
6 WORKING_DIRECTORY ${WORKING_DIR}
7− DEPENDS fake_install
7+ DEPENDS install
8− )
9−
10− add_custom_target(fake_install
11− COMMAND cmake --build ${CMAKE_BINARY_DIR} --target install
12 )
8 )
13
9
14 add_dependencies(autopilot autopilot-${TEST_NAME})
10 add_dependencies(autopilot autopilot-${TEST_NAME})
15−
16endfunction()
11endfunction()
data/51-unity8-greeter.confdeleted−2
@@ -1,2 +0,0 @@
1−[Seat:*]
2−greeter-session=unity8-greeter
data/CMakeLists.txtdeleted−27
@@ -1,27 +0,0 @@
1−# generate desktop files
2−configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
3−configure_file(${INDICATORS_CLIENT_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop @ONLY)
4−configure_file(${GREETER_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${GREETER_APP}.desktop @ONLY)
5−
6−# install desktop files
7−install(FILES
8− ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
9− ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop
10− DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
11− )
12−
13−install(FILES
14− ${CMAKE_CURRENT_BINARY_DIR}/${GREETER_APP}.desktop
15− DESTINATION ${CMAKE_INSTALL_DATADIR}/lightdm/greeters
16− )
17−
18−install(FILES
19− 51-unity8-greeter.conf
20− DESTINATION ${CMAKE_INSTALL_DATADIR}/lightdm/lightdm.conf.d
21− )
22−
23−add_custom_target(pkgversion ALL COMMAND dpkg-parsechangelog -l${CMAKE_SOURCE_DIR}/debian/changelog --show-field version > ${CMAKE_CURRENT_BINARY_DIR}/version)
24−
25−install(FILES com.canonical.Unity8.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
26−install(FILES com.canonical.Unity.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
27−install(FILES ${CMAKE_CURRENT_BINARY_DIR}/version DESTINATION ${CMAKE_INSTALL_LOCALSTATEDIR}/lib/unity8)
data/com.canonical.Unity.gschema.xmldeleted−255
@@ -1,255 +0,0 @@
1−<schemalist>
2− <enum id="form-factor-enum">
3− <value nick="Automatic" value="0" />
4− <value nick="Desktop" value="1" />
5− <value nick="Netbook" value="2" />
6− <value nick="TV" value="3" />
7− </enum>
8− <enum id="home-expanded-enum">
9− <value nick="Not Expanded" value="0" />
10− <value nick="Expanded" value="1" />
11− </enum>
12− <enum id="launcher-position-enum">
13− <value nick="Left" value="0" />
14− <value nick="Bottom" value="1" />
15− </enum>
16− <enum id="desktop-type-enum">
17− <value nick="Ubuntu" value="0" />
18− <value nick="UbuntuKylin" value="1" />
19− </enum>
20−
21− <schema path="/com/canonical/unity/" id="com.canonical.Unity" gettext-domain="unity">
22− <key enum="form-factor-enum" name="form-factor">
23− <default>"Automatic"</default>
24− <summary>The form factor Unity should target.</summary>
25− <description>The form factor chosen will affect the size and appearance of the Dash, Launcher and also the Window Management behaviour.</description>
26− </key>
27− <key enum="home-expanded-enum" name="home-expanded">
28− <default>"Expanded"</default>
29− <summary>Whether the home screen should be expanded.</summary>
30− <description>Whether the home screen should be expanded.</description>
31− </key>
32− <key enum="desktop-type-enum" name="desktop-type">
33− <default>"Ubuntu"</default>
34− <summary>The current desktop name.</summary>
35− <description>The current desktop name.</description>
36− </key>
37− <key type="i" name="minimize-count">
38− <default>0</default>
39− <summary>Number of times a normal window has been minimized.</summary>
40− <description>This is used to adjust the animation speed by making it progressively faster the more it is used.</description>
41− </key>
42− <key type="i" name="minimize-fast-duration">
43− <default>300</default>
44− <summary>The duration for the minimize animation when it is at its fastest setting.</summary>
45− <description>This is the duration that the minimize animation will have when it has been used more than an number of times equal minimize-speed-threshold.</description>
46− </key>
47− <key type="i" name="minimize-slow-duration">
48− <default>800</default>
49− <summary>The duration for the minimize animation when it is at its slowest setting.</summary>
50− <description>This is the duration that the minimize animation will have when it has never been used.</description>
51− </key>
52− <key type="i" name="minimize-speed-threshold">
53− <default>100</default>
54− <summary>The number of minimizations required to reach maximum speed.</summary>
55− <description>The speed of the minimize animation will progressively get faster as minimize-count approaches this value.</description>
56− </key>
57− <key type="b" name="double-click-activate">
58− <default>true</default>
59− <summary>Enable/Disable dash result double-click activation.</summary>
60− <description>This is used to enable/disable double-click result activation in the dash. Double-click to activate, single click preview</description>
61− </key>
62− <key type="b" name="integrated-menus">
63− <default>false</default>
64− <summary>Enable/Disable the integrated menus in Unity.</summary>
65− <description>When this is enabled, the application menus will be shown
66− on the window decoration, otherwise they will be always shown on the
67− unity top panel</description>
68− </key>
69− <key type="u" name="show-menus-now-delay">
70− <default>180</default>
71− <range min="0" max="5000"/>
72− <summary>Delay (in ms) before showing the menus when pressing Alt</summary>
73− <description>This allows tune the delay before presenting unity menus
74− (in non always-show-menus mode).</description>
75− </key>
76− <key type="b" name="always-show-menus">
77− <default>false</default>
78− <summary>Toggle the menu visibility based on mouse hovering.</summary>
79− <description>When this is enabled, the application menus will be always
80− shown (on the window decoration or in the unity panel, depending whether
81− integrated menus are enabled), otherwise they will be shown only when
82− the mouse cursor is over the relative mouse area.</description>
83− </key>
84− <key type="as" name="whitelist-repeated-keys">
85− <default>[
86− 'XF86KbdBrightnessUp',
87− 'XF86KbdBrightnessDown',
88− 'XF86MonBrightnessUp',
89− 'XF86MonBrightnessDown',
90− 'XF86AudioRaiseVolume',
91− 'XF86AudioLowerVolume'
92− ]</default>
93− <summary>List of keycodes that should be processed even if auto-repated.</summary>
94− <description>These keycodes are processed even if they are auto-repeated.</description>
95− </key>
96− <key type="b" name="pam-check-account-type">
97− <default>false</default>
98− <summary>Enable/Disable PAM account checking</summary>
99− <description>Whether PAM should check the result of account modules
100− when authenticating. Only do this if you have account
101− configured properly on your system.</description>
102− </key>
103− <key type="b" name="lowgfx">
104− <default>false</default>
105− <summary>Enable/Disable Low Graphics Mode</summary>
106− <description>Whether Unity runs in Low Graphics Mode.</description>
107− </key>
108− </schema>
109− <schema path="/com/canonical/unity/interface/" id="com.canonical.Unity.Interface" gettext-domain="unity">
110− <key type="d" name="text-scale-factor">
111− <default>1.0</default>
112− <range min="0.5" max="3.0"/>
113− <summary>Font scaling for unity and applications.</summary>
114− <description>This value defines the global font scaling used by both
115− unity and applications. It will match the current system font scaling.</description>
116− </key>
117− <key type="d" name="cursor-scale-factor">
118− <default>1.0</default>
119− <range min="0.5" max="3.0"/>
120− <summary>Mouse cursor scaling.</summary>
121− <description>This value defines the global mouse cursor scaling used by both
122− unity and applications. Changing this value allows to use a custom scaling
123− for the mouse cursor.</description>
124− </key>
125− <key type="s" name="app-scale-factor-monitor">
126− <default>''</default>
127− <summary>The name of the monitor that controls the global app scaling factor.</summary>
128− <description>This value defines the monitor that unity will use (if found) as reference
129− for scaling all the applications.</description>
130− </key>
131− <key type="b" name="app-fallback-to-maximum-scale-factor">
132− <default>true</default>
133− <summary>Use the maximum per-monitor scale-factor as application scale factor if no target monitor is found.</summary>
134− <description>When this is enabled, the applications scale factor will match
135− the scale factor of the monitor with the greater value, in case the monitor
136− defined in 'app-scale-factor-monitor' is not provided or available.</description>
137− </key>
138− </schema>
139− <schema path="/com/canonical/unity/launcher/" id="com.canonical.Unity.Launcher" gettext-domain="unity">
140− <key type="as" name="favorites">
141− <default>[
142− 'application://ubiquity.desktop',
143− 'application://org.gnome.Nautilus.desktop',
144− 'application://firefox.desktop',
145− 'application://libreoffice-writer.desktop',
146− 'application://libreoffice-calc.desktop',
147− 'application://libreoffice-impress.desktop',
148− 'application://org.gnome.Software.desktop',
149− 'application://ubuntu-amazon-default.desktop',
150− 'application://unity-control-center.desktop',
151− 'unity://running-apps',
152− 'unity://expo-icon',
153− 'unity://devices'
154− ]</default>
155− <summary>List of items that should be shown by default in the launcher</summary>
156− <description>These items can be: application://desktop-id.desktop, device://uiid and unity://special-id (including: unity://running-apps (icons of running applications) unity://devices (icons of attached devices), unity://expo-icon (icon of the workspace switcher) and unity://desktop-icon (the show-desktop icon)); the order of this list determines the launcher item's position.</description>
157− </key>
158− <key type="as" name="items">
159− <default>[
160− 'application:///dialer-app.desktop',
161− 'application:///messaging-app.desktop',
162− 'application:///address-book-app.desktop',
163− 'application:///ubuntu-system-settings.desktop',
164− 'appid://openstore.openstore-team/openstore/current-user-version',
165− 'appid://com.ubuntu.camera/camera/current-user-version',
166− 'appid://com.ubuntu.gallery/gallery/current-user-version',
167− 'application:///morph-browser.desktop'
168− ]</default>
169− <summary>List of items that should be shown by default in the launcher</summary>
170− <description>These items can be: application:///desktop-id.desktop or appid://package/app/current-user-version.</description>
171− </key>
172− <key type="s" name="favorite-migration">
173− <default>''</default>
174− <summary>Version of last migration done</summary>
175− <description>This is a detection key for the favorite migration script to know whether the needed migration is done or not.</description>
176− </key>
177− <key enum="launcher-position-enum" name="launcher-position">
178− <default>"Left"</default>
179− <summary>The position of launcher.</summary>
180− <description>The position of launcher.</description>
181− </key>
182− </schema>
183− <schema path="/com/canonical/unity/devices/" id="com.canonical.Unity.Devices" gettext-domain="unity">
184− <key type="as" name="blacklist">
185− <default>[]</default>
186− <summary>List of device uuid blacklist from the launcher.</summary>
187− <description>These devices are not shown in the launcher by default.</description>
188− </key>
189− </schema>
190− <schema path="/com/canonical/unity/dash/" id="com.canonical.Unity.Dash" gettext-domain="unity">
191− <key type="as" name="scopes">
192− <default>[ 'home.scope', 'applications.scope', 'files.scope', 'video.scope', 'music.scope', 'photos.scope', 'social.scope' ]</default>
193− <summary>List of scope ids specifying which scopes should be created and the order to display them in.</summary>
194− <description>The scopes listed in the scope bar will be ordered according to this list.</description>
195− </key>
196− <key type="as" name="favorite-scopes">
197− <default>[ 'scope://clickscope', 'scope://musicaggregator', 'scope://videoaggregator' ]</default>
198− <summary>List of scope queries specifying what should be displayed in the dash.</summary>
199− <description>List of favorite scopes displayed in the dash.</description>
200− </key>
201− </schema>
202− <schema path="/com/canonical/unity/decorations/" id="com.canonical.Unity.Decorations" gettext-domain="unity">
203− <key type="u" name="grab-wait">
204− <default>175</default>
205− <range min="0" max="1000"/>
206− <summary>Milliseconds to wait before considering a mouse pressure a grab</summary>
207− <description>The number of ms to wait before starting the window movement (and then
208− showing the proper mouse cursor, and grabbing the window)</description>
209− </key>
210− </schema>
211− <schema path="/com/canonical/unity/integrated-menus/" id="com.canonical.Unity.IntegratedMenus" gettext-domain="unity">
212− <key type="u" name="click-movement-threshold">
213− <default>15</default>
214− <range min="0" max="30"/>
215− <summary>Number of pixels to ignore on mouse pressure</summary>
216− <description>This value define how many pixels the user can move the mouse
217− when holding the mouse button, before we consider his action a movement
218− (to grab the window).</description>
219− </key>
220− <key type="u" name="double-click-wait">
221− <default>0</default>
222− <range min="0" max="300"/>
223− <summary>Milliseconds to wait before activating a menu after mouse release</summary>
224− <description>The number of ms to wait after a mouse button release event before considering
225− it a click. When this value is greater than 0, then it's possible to maximize
226− a window by double-clicking on its menus if the second click happens before the
227− specified value of ms is elapsed</description>
228− </key>
229− <key type="b" name="unfocused-windows-popup">
230− <default>true</default>
231− <summary>Whether to pop-up a menu when clicking over unfocused windows entries</summary>
232− <description>By disabling this setting you can make unity to only focus a window
233− when clicking over unfocused menu entries</description>
234− </key>
235− </schema>
236− <schema path="/com/canonical/unity/gestures/" id="com.canonical.Unity.Gestures" gettext-domain="unity">
237− <key type="b" name="launcher-drag">
238− <default>true</default>
239− <summary>Multi-touch gesture to reveal the launcher.</summary>
240− <description>When this is enabled, a 4 finger swipe from left to right will reveal launcher,
241− provided that the launcher is set to auto-hide.</description>
242− </key>
243− <key type="b" name="dash-tap">
244− <default>true</default>
245− <summary>Multi-touch gesture to open the dash.</summary>
246− <description>When this is enabled, a 4 finger tap will open the dash.</description>
247− </key>
248− <key type="b" name="windows-drag-pinch">
249− <default>true</default>
250− <summary>Multi-touch gestures to manage the windows.</summary>
251− <description>When this is enabled, 3 finger gestures such as drag, and pinch, will
252− help manage the windows.</description>
253− </key>
254− </schema>
255−</schemalist>
data/com.canonical.Unity8.gschema.xmldeleted−75
@@ -1,75 +0,0 @@
1−<schemalist>
2− <enum id="usage-mode-enum">
3− <value nick="Staged" value="0" />
4− <value nick="Windowed" value="1" />
5− <value nick="Automatic" value="2" />
6− </enum>
7−
8− <schema path="/com/canonical/unity8/" id="com.canonical.Unity8" gettext-domain="unity8">
9− <key enum="usage-mode-enum" name="usage-mode">
10− <default>"Automatic"</default>
11− <summary>The usage mode.</summary>
12− <description>The usage mode chosen will affect the Window Management behaviour.</description>
13− </key>
14− <key type="u" name="edge-barrier-sensitivity">
15− <default>50</default>
16− <range min="1" max="100"/>
17− <summary>Sensitivity of screen edge barriers for the mouse pointer.</summary>
18− <description>Some UI actions like revealing the launcher or the applications spread are triggered by pushing the mouse pointer against a screen edge. This key defines how much you have to push in order to trigger the associated action.</description>
19− </key>
20− <key type="u" name="edge-barrier-min-push">
21− <default>2</default>
22− <summary>Minimum push needed to overcome edge barrier</summary>
23− <description>How much you have to push (in grid units)the mouse against an edge barrier when sensibility is 100.</description>
24− </key>
25− <key type="u" name="edge-barrier-max-push">
26− <default>120</default>
27− <summary>Maximum push needed to overcome edge barrier</summary>
28− <description>How much you have to push (in grid units) the mouse against an edge barrier when sensibility is 1.</description>
29− </key>
30− <key type="u" name="edge-drag-width">
31− <default>2</default>
32− <summary>The width of the edge drag areas</summary>
33− <description>How big (in grid units) the edge-drag sensitive area should be.</description>
34− </key>
35− <key type="b" name="autohide-launcher">
36− <default>false</default>
37− <summary>Autohide the launcher</summary>
38− <description>This will only be applied in windowed mode. In staged mode, the launcher will always hide.</description>
39− </key>
40− <key type="u" name="launcher-width">
41− <default>8</default>
42− <range min="6" max="12"/>
43− <summary>Width of the launcher in grid units.</summary>
44− <description>Changes the width of the launcher in all usage modes.</description>
45− </key>
46− <key type="b" name="enable-indicator-menu">
47− <default>true</default>
48− <summary>Enable or disable the indicator pull down menus</summary>
49− <description>Toggle the availability of the indicator pull down menus</description>
50− </key>
51− <key type="s" name="appstore-uri">
52− <default>'appid://openstore.openstore-team/openstore/current-user-version'</default>
53− <summary>The uri to the app store</summary>
54− <description>This will be used whenever the user triggers an action to open the app store.</description>
55− </key>
56− <key type="b" name="always-show-osk">
57− <default>false</default>
58− <summary>Force showing/hiding the OSK</summary>
59− <description>Toggle the visibility of the On Screen Keyboard unconditionally</description>
60− </key>
61− <key type="b" name="osk-switch-visible">
62− <default>false</default>
63− <summary>Whether the OSK switch should be visible</summary>
64− <description>Toggle the visibility of the OSK switch</description>
65− </key>
66− </schema>
67−
68− <schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8">
69− <key type="x" name="locked-out-time">
70− <default>0</default>
71− <summary>When the greeter was last locked.</summary>
72− <description>If too many unsuccessful login attempts have been made in a row, the greeter locks you out for a while. This unix timestamp indicates when you were locked out, so unity8 knows when to let you back in.</description>
73− </key>
74− </schema>
75−</schemalist>
data/devices.confdeleted−30
@@ -1,30 +0,0 @@
1−# This file can hold multiple device configs. Devices are separated by sections.
2−#
3−# SupportedOrientations holds a list of all enabled orientations. A standard
4−# phone will usually have Portrait,Landcape,InvertedLandscape in order to
5−# disable upside down usage.
6−#
7−# PrimaryOrientation gives the orientation the device will start up with
8−# when there is no orientations sensor input available (yet) or lock to
9−# when an application specifies to be locked to PrimaryOrientation.
10−#
11−# The other Orientation settings can be used to re-map the orientations.
12−# A device might be used with different orientations than how the screen
13−# is physically mounted on the hardware.
14−#
15−# Category can be phone, tablet, or desktop. This option determines
16−# whether the side stage is shown (tablet) or not (phone). Using
17−# desktop will load the shell in windowed mode. Note that the user
18−# can override/change this by connecting input hardware or change
19−# user settings.
20−#
21−# Any options not listed will default to the values of the example below.
22−
23−# [devicename]
24−# SupportedOrientations=Portrait,InvertedPortrait,Landscape,InvertedLandscape
25−# PrimaryOrientation=PrimaryOrienation
26−# PortraitOrientation=Portrait
27−# InvertedPortraitOrientation=InvertedPortrait
28−# LandscapeOrientation=Landscape
29−# InvertedLandscapeOrientation=InvertedLandscape
30−# Category=phone
data/indicators-client.desktop.indeleted−9
@@ -1,9 +0,0 @@
1−[Desktop Entry]
2−Type=Application
3−Name=Indicators Client
4−Comment=Application for testing the Indicators system
5−Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/indicators-client
6−Terminal=false
7−Icon=
8−NoDisplay=false
9−X-Ubuntu-Touch=true
data/test.sensorsdeleted−12
@@ -1,12 +0,0 @@
1−create light 0 10 1
2−create accel 0 1000 0.1
3−create proximity
4−
5−200 proximity near
6−500 light 5
7−# simulate crash on the ground
8−500 accel 0.2 0.1 10
9−100 accel 0.2 0.2 1000
10−20 accel 0 0 0
11−10 proximity far
12−10 light 10
data/unity-mock-indicator-service.confdeleted−7
@@ -1,7 +0,0 @@
1−description "Unity Shell v8 Mock Indicator"
2−author "Nick Dedekind <nick.dedekind@canonical.com>"
3−
4−respawn
5−respawn limit 2 10
6−
7−exec ${BINARY:-unity-mock-indicator-service} $ARGS
data/unity8-filewatcher.confdeleted−13
@@ -1,13 +0,0 @@
1−description "File system watcher for unity8"
2−author "Michael Zanetti <michael.zanetti@canonical.com>"
3−
4−# This method of updating the launcher will not work in our new snappy world,
5−# neither for snaps installed in the system nor if we are running inside a snap.
6−# Plus it hardcodes the phablet user... To be replaced once bug 1630997 is
7−# fixed in ubuntu-app-launch.
8−
9−# Workaround for bug 1360208. ~ and * in one expression doesn't work currently
10−start on (file FILE=/home/phablet/.local/share/applications/*.desktop) or (file FILE=/usr/share/applications/*.desktop)
11−
12−exec dbus-send --type=method_call --dest=com.canonical.Unity.Launcher /com/canonical/Unity/Launcher com.canonical.Unity.Launcher.Refresh
13−
data/unity8-greeter-init.confdeleted−12
@@ -1,12 +0,0 @@
1−description "Unity 8 Greeter initialization"
2−author "Michael Terry <mterry@ubuntu.com>"
3−
4−start on unity8-greeter-started
5−task
6−emits indicator-services-start
7−
8−script
9− start --no-wait ofono-setup || true
10− initctl emit --no-wait indicator-services-start || true
11− start --no-wait maliit-server || true
12−end script
data/unity8-greeter-logrotate.confdeleted−14
@@ -1,14 +0,0 @@
1−description "Unity 8 Greeter logrotate support"
2−author "Michael Terry <mterry@ubuntu.com>"
3−
4−start on unity8-greeter-started
5−task
6−
7−script
8− # logrotate normally starts on startup and then sleeps for 60 seconds.
9− # Otherwise, it skips that sleep. Since we can't emit the startup signal
10− # for a unity8-greeter session, we have to trigger logrotate manually.
11− # So we do the sleep ourselves in its stead.
12− sleep 60
13− initctl emit :sys:rotate-logs
14−end script
data/unity8-greeter-wrapperdeleted−109
@@ -1,109 +0,0 @@
1−#!/bin/sh
2−# -*- Mode: sh; indent-tabs-mode: nil; tab-width: 4 -*-
3−#
4−# Copyright (C) 2011,2013,2016 Canonical Ltd
5−#
6−# This program is free software: you can redistribute it and/or modify it under
7−# the terms of the GNU General Public License as published by the Free Software
8−# Foundation, version 3 of the License.
9−#
10−# See http://www.gnu.org/copyleft/gpl.html the full text of the license.
11−
12−# This wrapper merely ensures that init and friends live only as long as this
13−# script does. Otherwise, it's very easy for some processes to not notice that
14−# the session died. We could try to do this in-process, but we want to do this
15−# cleanup even if the greeter aborts.
16−
17−trap cleanup TERM EXIT
18−
19−cleanup()
20−{
21− trap - TERM EXIT
22− # Kill upstart and indicators
23− if [ -n "$INIT_PID" ]; then
24− kill "$INIT_PID"
25− fi
26− if [ -n "$CMD_PID" ]; then
27− kill "$CMD_PID"
28− fi
29− exit 0
30−}
31−
32−set_greeter_var()
33−{
34− export "$1=$2"
35− gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "{'$1': '$2'}"
36− if [ -n "$INIT_PID" ]; then
37− initctl set-env --global "$1=$2"
38− fi
39−}
40−
41−SUB_SOCKET=$XDG_RUNTIME_DIR/mir_socket
42−rm -f $SUB_SOCKET # clear socket in case we were hard shut down
43−
44−echo "DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}" >"$XDG_RUNTIME_DIR/dbus-session"
45−
46−# If touch session script (which sets up grid units and mir variables) is available, use it
47−TOUCH_WRAPPER=
48−if which ubuntu-touch-session >/dev/null; then
49− TOUCH_WRAPPER=ubuntu-touch-session
50−fi
51−
52−# Advertise as a unity8 session, so that indicator-network will start.
53−export XDG_SESSION_DESKTOP=unity8
54−export DESKTOP_SESSION=$XDG_SESSION_DESKTOP
55−
56−set_greeter_var QT_IM_MODULE maliitphablet
57−set_greeter_var QT_QPA_PLATFORM ubuntumirclient
58−
59−# We disable ofono using pulse. It causes problems with racing with the user's
60−# pulse. We need to come up with a better long-term fix for this, because we
61−# eventually need the greeter to play ringtones for users that aren't logged in.
62−set_greeter_var PA_DISABLED 1
63−
64−# Normal unity8 sessions are entirely driven by Upstart. But greeters
65−# are special. They need access to the file descriptors that lightdm
66−# creates for them and don't want to start all the services that a normal
67−# session would. So it's inconvenient to live within an upstart session.
68−# But... we still want to use Upstart for some services. So launch here.
69−MIR_SOCKET=$SUB_SOCKET $TOUCH_WRAPPER upstart --user --no-startup-event &
70−INIT_PID=$!
71−while [ ! -e "$XDG_RUNTIME_DIR/upstart/sessions/$INIT_PID.session" ]; do sleep 0.1; done
72−. "$XDG_RUNTIME_DIR/upstart/sessions/$INIT_PID.session"
73−export UPSTART_SESSION
74−
75−# Connect upstart to system, but do first command in a loop to avoid any
76−# race condition between the session file above being written and upstart being
77−# ready to handle requests.
78−while ! initctl notify-dbus-address "$DBUS_SESSION_BUS_ADDRESS"; do sleep 0.1; done
79−initctl start notify-cgmanager
80−
81−# Start any pre-greeter tasks if needed (like wizard)
82−initctl emit unity8-greeter-starting
83−
84−# Define language here for phone if available. When phone user switches their
85−# language, they expect that to affect the greeter too. But the user doesn't
86−# have permission to switch system language, only their own. So we notice if
87−# the phablet user exists and use their language if so. TODO: talk to design
88−# about whether we should switch language on fly as users are selected (this
89−# is very hard to do technically).
90−#
91−# Do this after unity8-greeter-starting, in case a customization upstart job
92−# changes language.
93−if [ "$(id -u phablet 2>/dev/null)" = "32011" ]; then
94− USER_LANG=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User Language | cut -d\' -f2)
95− if [ -n "$USER_LANG" ]; then
96− set_greeter_var LANGUAGE "$USER_LANG"
97− fi
98− USER_LOCALE=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User FormatsLocale | cut -d\' -f2)
99− if [ -n "$USER_LOCALE" ]; then
100− set_greeter_var LANG "$USER_LOCALE"
101− set_greeter_var LC_ALL "$USER_LOCALE"
102− fi
103−fi
104−
105−# And finally actually start the greeter
106−exec env MIR_SERVER_FILE=$SUB_SOCKET $TOUCH_WRAPPER $@ &
107−CMD_PID=$!
108−wait $CMD_PID
109−CMD_PID=
data/unity8-greeter.desktop.indeleted−7
@@ -1,7 +0,0 @@
1−[Desktop Entry]
2−Type=Application
3−Name=Unity 8 Greeter
4−Comment=The converged Unity shell's Greeter
5−Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8-greeter-wrapper @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8 --mode=greeter
6−X-LightDM-Session-Type=mir
7−X-Ubuntu-Touch=true
data/unity8-greeter.pkladeleted−44
@@ -1,44 +0,0 @@
1−# DO NOT EDIT THIS FILE, it will be overwritten on update
2−# Place your local configurations under /etc/polkit-1/localauthority/
3−
4−[Disable Controlling of Network Devices]
5−Identity=unix-user:lightdm
6−Action=org.freedesktop.NetworkManager.enable-disable-network;org.freedesktop.NetworkManager.enable-disable-wifi;org.freedesktop.NetworkManager.enable-disable-wwan;org.freedesktop.NetworkManager.enable-disable-wimax;
7−ResultActive=no
8−ResultInactive=no
9−ResultsAny=no
10−
11−[Disable Sleep and Wake]
12−Identity=unix-user:lightdm
13−Action=org.freedesktop.NetworkManager.sleep-wake
14−ResultActive=no
15−ResultInactive=no
16−ResultsAny=no
17−
18−[Disable WiFi Sharing]
19−Identity=unix-user:lightdm
20−Action=org.freedesktop.NetworkManager.wifi.share.protected;org.freedesktop.NetworkManager.wifi.share.open
21−ResultActive=no
22−ResultInactive=no
23−ResultsAny=no
24−
25−[Disable Settings Modifications]
26−Identity=unix-user:lightdm
27−Action=org.freedesktop.NetworkManager.settings.modify.own;org.freedesktop.NetworkManager.settings.modify.system;org.freedesktop.NetworkManager.settings.modify.hostname
28−ResultActive=no
29−ResultInactive=no
30−ResultsAny=no
31−
32−[Disable User Connections]
33−Identity=unix-user:lightdm
34−Action=org.freedesktop.NetworkManager.use-user-connections
35−ResultActive=no
36−ResultInactive=no
37−ResultsAny=no
38−
39−[Enable Controlling of Network Connections]
40−Identity=unix-user:lightdm
41−Action=org.freedesktop.NetworkManager.network-control
42−ResultActive=yes
43−ResultInactive=no
44−ResultsAny=no
data/unity8.conf+2−92
@@ -1,99 +1,9 @@
1description "Unity Shell v8"
1description "Unity Shell v8"
2author "Ricardo Mendoza <ricmm@ubuntu.com>"
2author "Ricardo Mendoza <ricmm@ubuntu.com>"
3
3
4−emits indicator-services-start
5−emits indicator-services-end
6−
7−start on ((xsession SESSION=ubuntu-touch) or (xsession SESSION=unity8-mir) or (xsession SESSION=unity8)) and started dbus
4+start on ((xsession SESSION=ubuntu-touch) or (xsession SESSION=ubuntu-touch-surfaceflinger)) and started dbus
8stop on desktop-end
5stop on desktop-end
9
6
10−kill timeout 120
11−
12−#
13−# Ensure the shell always gets unthrottled touch events, so that applications
14−# who want full speed low-latency input can get it (LP: #1497105) and so that
15−# apps can use QML touch compression safely (the QML touch compression
16−# algorithm does not support nesting well - LP: #1486341, LP: #1556763 - so
17−# must be fed by the raw input event stream from Unity8).
18−#
19−env QML_NO_TOUCH_COMPRESSION=1
20−
21respawn
7respawn
22−expect stop
23−
24−# FIXME Create an autopilot test that makes sure start+stop and restart
25−# work fine at least 2 times
26−
27−pre-start script
28− # Tell unity-mir to raise SIGSTOP after we start
29− initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
30−
31− # Save original value of MIR_SOCKET so that we can restore it when stopped,
32− # as we modify the variable for future jobs, including ourself.
33− initctl set-env UNITY_MIR_SOCKET=$MIR_SOCKET
34−
35− # Decide where we are going to put our own socket file
36− if [ -n "$SNAP" ]; then
37− # In snappy, we want to hard code our path because our apparmor profile
38− # only lets us put the socket in one place. And consumers expect it
39− # there.
40− MIR_SERVER_FILE=/run/user/$(id -u)/mir_socket
41− else
42− MIR_SERVER_FILE=$XDG_RUNTIME_DIR/mir_socket
43− fi
44− initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
45−
46− # Point all future jobs in this session to our Mir socket instead of
47− # unity-system-compositor's socket.
48− initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
49− gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
50−
51− # Remove the normal and trusted sockets if still there
52− if [ -S "$MIR_SERVER_FILE" ]; then
53− rm "$MIR_SERVER_FILE"
54− fi
55−
56− if [ -S "${MIR_SERVER_FILE}_trusted" ]; then
57− rm "${MIR_SERVER_FILE}_trusted"
58− fi
59−
60− initctl set-env --global MIR_SERVER_PROMPT_FILE=1
61−
62− # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
63− # issues (LP: #1486341, LP: #1556763). As a bonus, this eliminates most of
64− # the lag seen in the indicator panel pull-down (LP: #1488327) and also
65− # reduces lag seen in apps:
66− initctl set-env --global QML_NO_TOUCH_COMPRESSION=1
67−
68− # Workaround for text not rendering correctly
69− initctl set-env --global QT_ENABLE_GLYPH_CACHE_WORKAROUND=1
70−
71− if [ "$XDG_SESSION_DESKTOP" = "ubuntu-touch" ]; then
72− # On Ubuntu Touch, we currently use a trick where we auto-login the
73− # user without a LightDM greeter at all. In this case, we want to
74− # start with the lockscreen visible. Once we switch to using a
75− # proper greeter for the first login, we can remove this code path.
76− initctl set-env MODE=full-greeter
77− else
78− initctl set-env MODE=full-shell
79− fi
80−
81− # HACK! WORKAROUND FOR HALIUM MISSING UBUNTU_PLATFORM_API
82− if [ ! -f /system/lib/libubuntu_application_api.so ]; then
83− initctl set-env --global UBUNTU_PLATFORM_API_BACKEND=test.so.3
84− initctl set-env --global UBUNTU_PLATFORM_API_SENSOR_TEST=/etc/ubuntusensors/test.sensors
85− fi
86−end script
87−
88−exec ${BINARY:-unity8} --mode=$MODE $ARGS
89−
90−post-start script
91− initctl emit --no-wait indicator-services-start
92−end script
93
8
94−post-stop script
9+exec ${BINARY:-unity8} $ARGS
95− initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
96− initctl unset-env --global MIR_SERVER_PROMPT_FILE
97− initctl emit application-end
98− initctl emit indicator-services-end
99−end script
debian/bileto_pre_release_hookdeleted−5
@@ -1,5 +0,0 @@
1−#!/bin/sh
2−
3−set -eux
4−
5−sh ./po/update-unity-pot
debian/changelog+16−5616

This diff is too big to show here.

debian/control+98−240

This diff is too big to show here.

debian/copyright−21

This diff is too big to show here.

debian/indicators-client.install−1

This diff is too big to show here.

debian/rules+14−29

This diff is too big to show here.

debian/scopes-recommends-generatornew file+27

This diff is too big to show here.

debian/shlibs.localdeleted−1

This diff is too big to show here.

debian/source/formatnew file+1

This diff is too big to show here.

debian/tests/autopilot.shdeleted−13

This diff is too big to show here.

debian/tests/controldeleted−11

This diff is too big to show here.

debian/tests/qmluitests.shdeleted−11

This diff is too big to show here.

debian/unity8-autopilot.install−1

This diff is too big to show here.

debian/unity8-common.installdeleted−5

This diff is too big to show here.

debian/unity8-common.udevdeleted−2

This diff is too big to show here.

debian/unity8-doc.installdeleted−2

This diff is too big to show here.

debian/unity8-fake-env.installnew file+2

This diff is too big to show here.

debian/unity8-greeter.installdeleted−5

This diff is too big to show here.

debian/unity8-private.install+4−9

This diff is too big to show here.

debian/unity8-schemas.installdeleted−1

This diff is too big to show here.

debian/unity8-tests.installdeleted−9

This diff is too big to show here.

debian/unity8-tests.lintian-overridesdeleted−1

This diff is too big to show here.

debian/unity8.install+10−13

This diff is too big to show here.

doc/CMakeLists.txtdeleted−40

This diff is too big to show here.

doc/Doxyfile.indeleted−2317

This diff is too big to show here.

doc/devices.confdeleted−45

This diff is too big to show here.

graphics/12_10_background_wide@12.pngnew file

Binary file not shown.

graphics/applicationIcons/angrybirds@18.pngnew file

Binary file not shown.

graphics/applicationIcons/browser@18.pngnew file

Binary file not shown.

graphics/applicationIcons/calendar@18.pngnew file

Binary file not shown.

graphics/applicationIcons/camera@18.pngnew file

Binary file not shown.

graphics/applicationIcons/contacts-app@18.pngnew file

Binary file not shown.

graphics/applicationIcons/dash@18.pngnew file

Binary file not shown.

graphics/applicationIcons/evernote@18.pngnew file

Binary file not shown.

graphics/applicationIcons/facebook@18.pngnew file

Binary file not shown.

graphics/applicationIcons/gallery@18.pngnew file

Binary file not shown.

graphics/applicationIcons/gmail@18.pngnew file

Binary file not shown.

graphics/applicationIcons/map@18.pngnew file

Binary file not shown.

graphics/applicationIcons/media-player@18.pngnew file

Binary file not shown.

graphics/applicationIcons/messages-app@18.pngnew file

Binary file not shown.

graphics/applicationIcons/music@18.pngnew file

Binary file not shown.

graphics/applicationIcons/notepad@18.pngnew file

Binary file not shown.

graphics/applicationIcons/phone-app@18.pngnew file

Binary file not shown.

graphics/applicationIcons/pinterest@18.pngnew file

Binary file not shown.

graphics/applicationIcons/ski_safari@18.pngnew file

Binary file not shown.

graphics/applicationIcons/skype@18.pngnew file

Binary file not shown.

graphics/applicationIcons/soundcloud@18.pngnew file

Binary file not shown.

graphics/applicationIcons/system-settings@18.pngnew file

Binary file not shown.

graphics/applicationIcons/twitter@18.pngnew file

Binary file not shown.

graphics/applicationIcons/weather@18.pngnew file

Binary file not shown.

graphics/applicationIcons/wikipedia@18.pngnew file

Binary file not shown.

graphics/applicationIcons/youtube@18.pngnew file

Binary file not shown.

graphics/avatars/amanda@12.pngnew file

Binary file not shown.

graphics/avatars/anna_olsson@12.pngnew file

Binary file not shown.

graphics/avatars/funky@12.pngnew file

Binary file not shown.

graphics/clock@18.pngnew file

Binary file not shown.

graphics/phone_background.jpgnew file

Binary file not shown.

graphics/tablet_background.jpgnew file

Binary file not shown.

include/CMakeLists.txtdeleted−1

This diff is too big to show here.

include/paths.h.indeleted−175

This diff is too big to show here.

main.cppnew file+223

This diff is too big to show here.

paths.h.innew file+87

This diff is too big to show here.

plugins/AccountsService/50-com.canonical.unity.AccountsService.pklanew file+6

This diff is too big to show here.

plugins/AccountsService/AccountsService.cpp+47−365

This diff is too big to show here.

plugins/AccountsService/AccountsService.h+12−91

This diff is too big to show here.

plugins/AccountsService/AccountsServiceDBusAdaptor.cpp+30−56

This diff is too big to show here.

plugins/AccountsService/AccountsServiceDBusAdaptor.h+6−10

This diff is too big to show here.

plugins/AccountsService/CMakeLists.txt+15−6

This diff is too big to show here.

plugins/AccountsService/com.canonical.unity.AccountsService.policynew file+24

This diff is too big to show here.

plugins/AccountsService/com.canonical.unity.AccountsService.xml+6−43

This diff is too big to show here.

plugins/AccountsService/plugin.cpp+1−2

This diff is too big to show here.

plugins/AccountsService/plugin.h+1−1

This diff is too big to show here.

plugins/AccountsService/qmldir+1−1

This diff is too big to show here.

plugins/CMakeLists.txt+2−21

This diff is too big to show here.

plugins/Cursor/3rd_party/CMakeLists.txtdeleted−1

This diff is too big to show here.

plugins/Cursor/3rd_party/xcursor/CMakeLists.txtdeleted−15

This diff is too big to show here.

plugins/Cursor/3rd_party/xcursor/xcursor.cdeleted−968

This diff is too big to show here.

plugins/Cursor/3rd_party/xcursor/xcursor.hdeleted−65

This diff is too big to show here.

plugins/Cursor/CMakeLists.txtdeleted−32

This diff is too big to show here.

plugins/Cursor/Cursor.qmldeleted−62

This diff is too big to show here.

plugins/Cursor/CursorImageInfo.cppdeleted−115

This diff is too big to show here.

plugins/Cursor/CursorImageInfo.hdeleted−82

This diff is too big to show here.

plugins/Cursor/CursorImageProvider.cppdeleted−337

This diff is too big to show here.

plugins/Cursor/CursorImageProvider.hdeleted−103

This diff is too big to show here.

plugins/Cursor/MousePointer.cppdeleted−235

This diff is too big to show here.

plugins/Cursor/MousePointer.hdeleted−92

This diff is too big to show here.

plugins/Cursor/plugin.cppdeleted−41

This diff is too big to show here.

plugins/Cursor/plugin.hdeleted−33

This diff is too big to show here.

plugins/Cursor/qmldirdeleted−3

This diff is too big to show here.

plugins/GlobalShortcut/CMakeLists.txtdeleted−10

This diff is too big to show here.

plugins/GlobalShortcut/globalshortcut.cppdeleted−91

This diff is too big to show here.

plugins/GlobalShortcut/globalshortcut.hdeleted−81

This diff is too big to show here.

plugins/GlobalShortcut/globalshortcutregistry.cppdeleted−125

This diff is too big to show here.

plugins/GlobalShortcut/globalshortcutregistry.hdeleted−70

This diff is too big to show here.

plugins/GlobalShortcut/plugin.cppdeleted−27

This diff is too big to show here.

plugins/GlobalShortcut/plugin.hdeleted−32

This diff is too big to show here.

plugins/GlobalShortcut/qmldirdeleted−2

This diff is too big to show here.

plugins/Greeter/CMakeLists.txtdeleted−6

This diff is too big to show here.

plugins/Greeter/Unity/CMakeLists.txtdeleted−1

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/CMakeLists.txtdeleted−35

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/launcheritem.cppdeleted−218

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/launcheritem.hdeleted−84

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/launchermodelas.cppdeleted−303

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/launchermodelas.hdeleted−77

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/plugin.cppdeleted−46

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/plugin.hdeleted−32

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/qmldirdeleted−3

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/quicklistmodel.cppdeleted−72

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/quicklistmodel.hdeleted−55

This diff is too big to show here.

plugins/HudClient/CMakeLists.txtnew file+43

This diff is too big to show here.

plugins/HudClient/hudclient.cppnew file+309

This diff is too big to show here.

plugins/HudClient/hudclient.hnew file+71

This diff is too big to show here.

plugins/HudClient/hudtoolbarmodel.cppnew file+98

This diff is too big to show here.

tests/mocks/Unity/Application/MirMock.h → plugins/HudClient/hudtoolbarmodel.hrenamed+17−16

This diff is too big to show here.

tests/mocks/Lights/plugin.cpp → plugins/HudClient/plugin.cpprenamed+15−12

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/plugin.h → plugins/HudClient/plugin.hrenamed+7−7

This diff is too big to show here.

plugins/HudClient/qmldirnew file+3

This diff is too big to show here.

plugins/HudClient/volumepeakdetector.cppnew file+223

This diff is too big to show here.

plugins/HudClient/volumepeakdetector.hnew file+78

This diff is too big to show here.

plugins/LightDM/CMakeLists.txt+26−12

This diff is too big to show here.

plugins/LightDM/DBusGreeter.cppdeleted−50

This diff is too big to show here.

plugins/LightDM/DBusGreeter.hdeleted−52

This diff is too big to show here.

plugins/LightDM/DBusGreeterList.cppdeleted−56

This diff is too big to show here.

plugins/LightDM/DBusGreeterList.hdeleted−57

This diff is too big to show here.

plugins/LightDM/FullLightDM/CMakeLists.txtdeleted−32

This diff is too big to show here.

plugins/LightDM/FullLightDM/qmldirdeleted−3

This diff is too big to show here.

plugins/LightDM/Greeter.cpp+36−182

This diff is too big to show here.

plugins/LightDM/Greeter.h+13−35

This diff is too big to show here.

plugins/LightDM/GreeterPrivate.hdeleted−45

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/CMakeLists.txtdeleted−33

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/CMakeLists.txtdeleted−54

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/GreeterPrivate.cppdeleted−309

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModel.cppdeleted−87

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModel.hdeleted−72

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.cppdeleted−36

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.hdeleted−54

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.cppdeleted−94

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.hdeleted−72

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/qmldirdeleted−3

This diff is too big to show here.

plugins/LightDM/PromptsModel.cppdeleted−97

This diff is too big to show here.

plugins/LightDM/PromptsModel.hdeleted−70

This diff is too big to show here.

plugins/LightDM/SessionsModel.cppdeleted−135

This diff is too big to show here.

plugins/LightDM/SessionsModel.hdeleted−66

This diff is too big to show here.

plugins/LightDM/UsersModel.cpp+15−183

This diff is too big to show here.

plugins/LightDM/UsersModel.h+10−8

This diff is too big to show here.

plugins/LightDM/plugin.cpp+8−46

This diff is too big to show here.

plugins/LightDM/plugin.h+6−4

This diff is too big to show here.

plugins/LightDM/qmldir+3−3

This diff is too big to show here.

plugins/Lights/CMakeLists.txtdeleted−23

This diff is too big to show here.

plugins/Lights/HfdLights.cppdeleted−62

This diff is too big to show here.

plugins/Lights/LegacyLights.cppdeleted−91

This diff is too big to show here.

plugins/Lights/Lights.cppdeleted−101

This diff is too big to show here.

plugins/Lights/Lights.hdeleted−71

This diff is too big to show here.

plugins/Lights/plugin.cppdeleted−54

This diff is too big to show here.

plugins/Lights/plugin.hdeleted−34

This diff is too big to show here.

plugins/Lights/qmldirdeleted−3

This diff is too big to show here.

plugins/ListViewWithPageHeader/CMakeLists.txtnew file+42

This diff is too big to show here.

plugins/ListViewWithPageHeader/listviewwithpageheader.cppnew file+1274

This diff is too big to show here.

plugins/ListViewWithPageHeader/listviewwithpageheader.hnew file+212

This diff is too big to show here.

plugins/Unity/Platform/plugin.cpp → plugins/ListViewWithPageHeader/plugin.cpprenamed+9−7

This diff is too big to show here.

plugins/Wizard/Utils/plugin.h → plugins/ListViewWithPageHeader/plugin.hrenamed+4−4

This diff is too big to show here.

plugins/ListViewWithPageHeader/qmldirnew file+3

This diff is too big to show here.

plugins/Powerd/CMakeLists.txt+4−8

This diff is too big to show here.

plugins/Powerd/Powerd.cpp+13−67

This diff is too big to show here.

plugins/Powerd/Powerd.h+9−25

This diff is too big to show here.

plugins/Powerd/plugin.h+1−1

This diff is too big to show here.

plugins/Powerd/qmldir+1−1

This diff is too big to show here.

plugins/ScreenshotDirectory/CMakeLists.txtdeleted−9

This diff is too big to show here.

plugins/ScreenshotDirectory/ScreenGrabber.qmltypesdeleted−17

This diff is too big to show here.

plugins/ScreenshotDirectory/ScreenshotDirectory.cppdeleted−64

This diff is too big to show here.

plugins/ScreenshotDirectory/ScreenshotDirectory.hdeleted−39

This diff is too big to show here.

plugins/ScreenshotDirectory/plugin.cppdeleted−26

This diff is too big to show here.

plugins/ScreenshotDirectory/plugin.hdeleted−31

This diff is too big to show here.

plugins/ScreenshotDirectory/qmldirdeleted−2

This diff is too big to show here.

plugins/SessionBroadcast/CMakeLists.txt+5−6

This diff is too big to show here.

plugins/SessionBroadcast/SessionBroadcast.cpp+10−40

This diff is too big to show here.

plugins/SessionBroadcast/SessionBroadcast.h+3−13

This diff is too big to show here.

plugins/SessionBroadcast/plugin.cpp+1−1

This diff is too big to show here.

plugins/SessionBroadcast/plugin.h+1−1

This diff is too big to show here.

plugins/SessionBroadcast/qmldir+1−1

This diff is too big to show here.

plugins/UInput/CMakeLists.txtdeleted−7

This diff is too big to show here.

plugins/UInput/plugin.cppdeleted−26

This diff is too big to show here.

plugins/UInput/qmldirdeleted−3

This diff is too big to show here.

plugins/UInput/uinput.cppdeleted−182

This diff is too big to show here.

plugins/UInput/uinput.hdeleted−61

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt+9−7

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.cpp+8−9

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.h+2−3

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.cpp+2−2

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.h+15−82

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/interface/metatypes.h+6−3

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/plugin.h+2−2

This diff is too big to show here.

plugins/Ubuntu/DownloadDaemonListener/qmldir+1−1

This diff is too big to show here.

plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp+18−9

This diff is too big to show here.

plugins/Ubuntu/Gestures/AxisVelocityCalculator.h+18−11

This diff is too big to show here.

plugins/Ubuntu/Gestures/CMakeLists.txt+10−32

This diff is too big to show here.

plugins/Ubuntu/Gestures/Damper.hnew file+87

This diff is too big to show here.

plugins/Ubuntu/Gestures/Direction.cpp+4−11

This diff is too big to show here.

plugins/Ubuntu/Gestures/Direction.h+5−8

This diff is too big to show here.

plugins/Ubuntu/Gestures/DirectionalDragArea.cppnew file+461

This diff is too big to show here.

plugins/Ubuntu/Gestures/DirectionalDragArea.hnew file+251

This diff is too big to show here.

plugins/Ubuntu/Gestures/MouseEventGenerator.cppdeleted−64

This diff is too big to show here.

plugins/Ubuntu/Gestures/MouseEventGenerator.hdeleted−48

This diff is too big to show here.

plugins/Ubuntu/Gestures/PressedOutsideNotifier.cppdeleted−119

This diff is too big to show here.

plugins/Ubuntu/Gestures/PressedOutsideNotifier.hdeleted−62

This diff is too big to show here.

plugins/Ubuntu/Gestures/TouchDispatcher.cppdeleted−398

This diff is too big to show here.

plugins/Ubuntu/Gestures/TouchDispatcher.hdeleted−96

This diff is too big to show here.

plugins/Ubuntu/Gestures/TouchGate.cppdeleted−290

This diff is too big to show here.

plugins/Ubuntu/Gestures/TouchGate.hdeleted−125

This diff is too big to show here.

plugins/Ubuntu/Gestures/TouchGestureArea.cppdeleted−879

This diff is too big to show here.

plugins/Ubuntu/Gestures/TouchGestureArea.hdeleted−229

This diff is too big to show here.

plugins/Ubuntu/Gestures/UbuntuGesturesQmlGlobal.h → plugins/Ubuntu/Gestures/UbuntuGesturesGlobal.hrenamed+3−3

This diff is too big to show here.

plugins/Ubuntu/Gestures/plugin.cpp+4−11

This diff is too big to show here.

plugins/Ubuntu/Gestures/plugin.h+2−2

This diff is too big to show here.

plugins/Ubuntu/Gestures/qmldir+2−2

This diff is too big to show here.

plugins/Unity/ApplicationMenu/CMakeLists.txtdeleted−19

This diff is too big to show here.

plugins/Unity/ApplicationMenu/applicationmenuregistry.cppdeleted−141

This diff is too big to show here.

plugins/Unity/ApplicationMenu/applicationmenuregistry.hdeleted−83

This diff is too big to show here.

plugins/Unity/ApplicationMenu/com.ubuntu.MenuRegistrar.xmldeleted−83

This diff is too big to show here.

plugins/Unity/ApplicationMenu/dbusapplicationmenuregistry.cppdeleted−44

This diff is too big to show here.

plugins/Unity/ApplicationMenu/dbusapplicationmenuregistry.hdeleted−34

This diff is too big to show here.

plugins/Unity/ApplicationMenu/plugin.cppdeleted−42

This diff is too big to show here.

plugins/Unity/ApplicationMenu/plugin.hdeleted−32

This diff is too big to show here.

plugins/Unity/ApplicationMenu/qmldirdeleted−3

This diff is too big to show here.

plugins/Unity/CMakeLists.txt+69−5

This diff is too big to show here.

plugins/Unity/Connectivity/CMakeLists.txtdeleted−10

This diff is too big to show here.

plugins/Unity/Connectivity/Connectivity.cppdeleted−33

This diff is too big to show here.

plugins/Unity/Connectivity/Connectivity.hdeleted−34

This diff is too big to show here.

plugins/Unity/Connectivity/plugin.cppdeleted−34

This diff is too big to show here.

plugins/Unity/Connectivity/plugin.hdeleted−31

This diff is too big to show here.

plugins/Unity/Connectivity/qmldirdeleted−3

This diff is too big to show here.

plugins/Unity/Indicators/CMakeLists.txt+30−14

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/CMakeLists.txtnew file+1

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/ActionTextField.qmlnew file+69

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/CMakeLists.txtnew file+5

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qmlnew file+91

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/HeroMessage.qmlnew file+123

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qmlnew file+161

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qmlnew file+179

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/QuickReply.qmlnew file+165

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qmlnew file+107

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/SnapDecision.qmlnew file+167

This diff is too big to show here.

tests/mocks/QMenuModel/dbus-enums.h → plugins/Unity/Indicators/Messaging/qml/TextMessage.qmlrenamed+19−27

This diff is too big to show here.

plugins/Unity/Indicators/Messaging/qml/qmldirnew file+12

This diff is too big to show here.

plugins/Unity/Indicators/Network/CMakeLists.txtnew file+1

This diff is too big to show here.

plugins/Unity/Indicators/Network/qml/AccessPoint.qmlnew file+117

This diff is too big to show here.

plugins/Unity/Indicators/Network/qml/CMakeLists.txtnew file+5

This diff is too big to show here.

plugins/Unity/Indicators/Network/qml/qmldirnew file+3

This diff is too big to show here.

plugins/Unity/Indicators/actionrootstate.cppdeleted−97

This diff is too big to show here.

plugins/Unity/Indicators/actionrootstate.hdeleted−55

This diff is too big to show here.

plugins/Unity/Indicators/indicator.cpp+20−26

This diff is too big to show here.

plugins/Unity/Indicators/indicator.h+1−5

This diff is too big to show here.

plugins/Unity/Indicators/indicators.h+9−6

This diff is too big to show here.

plugins/Unity/Indicators/indicatorsmanager.cpp+52−45

This diff is too big to show here.

plugins/Unity/Indicators/indicatorsmanager.h+4−9

This diff is too big to show here.

plugins/Unity/Indicators/indicatorsmodel.cpp+19−50

This diff is too big to show here.

plugins/Unity/Indicators/indicatorsmodel.h+7−20

This diff is too big to show here.

plugins/Unity/Indicators/menucontentactivator.cpp+7−6

This diff is too big to show here.

plugins/Unity/Indicators/menucontentactivator.h+2−2

This diff is too big to show here.

plugins/Unity/Indicators/modelactionrootstate.cppdeleted−204

This diff is too big to show here.

plugins/Unity/Indicators/modelactionrootstate.hdeleted−72

This diff is too big to show here.

plugins/Unity/Indicators/modelprinter.cpp+15−30

This diff is too big to show here.

plugins/Unity/Indicators/modelprinter.h+3−4

This diff is too big to show here.

plugins/Unity/Indicators/plugin.cpp+15−17

This diff is too big to show here.

plugins/Unity/Indicators/plugin.h+2−2

This diff is too big to show here.

tests/mocks/Unity/Notifications/plugin.h → plugins/Unity/Indicators/qml/BaseMenuItem.qmlrenamed+17−13

This diff is too big to show here.

plugins/Unity/Indicators/qml/ButtonMenuItem.qmlnew file+44

This diff is too big to show here.

plugins/Unity/Indicators/qml/CMakeLists.txtnew file+5

This diff is too big to show here.

plugins/Unity/Indicators/qml/CachedUnityMenuModel.qmlnew file+60

This diff is too big to show here.

tests/mocks/Unity/InputInfo/plugin.h → plugins/Unity/Indicators/qml/DivMenuItem.qmlrenamed+10−14

This diff is too big to show here.

tests/mocks/Unity/Notifications/plugin.cpp → plugins/Unity/Indicators/qml/FramedMenuItem.qmlrenamed+19−13

This diff is too big to show here.

plugins/Unity/Indicators/qml/HLine.qmlnew file+29

This diff is too big to show here.

qml/Panel/Indicators/IndicatorBase.qml → plugins/Unity/Indicators/qml/IndicatorBase.qmlrenamed+15−11

This diff is too big to show here.

plugins/Unity/Indicators/qml/IndicatorPage.qmlnew file+205

This diff is too big to show here.

qml/Panel/Indicators/IndicatorDelegate.qml → plugins/Unity/Indicators/qml/IndicatorWidget.qmlrenamed+6−3

This diff is too big to show here.

plugins/Unity/Indicators/qml/MenuItemFactory.qmlnew file+248

This diff is too big to show here.

qml/Panel/Indicators/client/IndicatorsTree.qml → plugins/Unity/Indicators/qml/ProgressMenuItem.qmlrenamed+14−17

This diff is too big to show here.

plugins/Unity/Indicators/qml/RemoveBackground.qmlnew file+55

This diff is too big to show here.

plugins/Unity/Indicators/qml/SectionMenuItem.qmlnew file+54

This diff is too big to show here.

plugins/Unity/Indicators/qml/SliderMenuItem.qmlnew file+106

This diff is too big to show here.

plugins/Unity/Indicators/qml/StandardMenuItem.qmlnew file+71

This diff is too big to show here.

plugins/Unity/Indicators/qml/SwitchMenuItem.qmlnew file+53

This diff is too big to show here.

plugins/Unity/Indicators/qml/qmldirnew file+23

This diff is too big to show here.

plugins/Unity/Indicators/qmldirdeleted−3

This diff is too big to show here.

plugins/Unity/Indicators/resources/artwork/messaging/default_app.svgnew file+42

This diff is too big to show here.

plugins/Unity/Indicators/resources/artwork/messaging/default_contact.pngnew file

Binary file not shown.

plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.pngnew file

Binary file not shown.

plugins/Unity/Indicators/resources/artwork/network/secure.svgnew file+71

This diff is too big to show here.

plugins/Unity/Indicators/resources/indicators.qrcnew file+8

This diff is too big to show here.

plugins/Unity/Indicators/rootactionstate.cppnew file+299

This diff is too big to show here.

plugins/Unity/Indicators/rootstateparser.h → plugins/Unity/Indicators/rootactionstate.hrenamed+37−22

This diff is too big to show here.

plugins/Unity/Indicators/rootstateparser.cppdeleted−231

This diff is too big to show here.

plugins/Unity/Indicators/sharedunitymenumodel.cppdeleted−96

This diff is too big to show here.

plugins/Unity/Indicators/sharedunitymenumodel.hdeleted−66

This diff is too big to show here.

plugins/Unity/Indicators/timeformatter.cppnew file+172

This diff is too big to show here.

plugins/Unity/Indicators/timeformatter.hnew file+54

This diff is too big to show here.

plugins/Unity/Indicators/unitymenumodelcache.cpp+9−32

This diff is too big to show here.

plugins/Unity/Indicators/unitymenumodelcache.h+6−12

This diff is too big to show here.

plugins/Unity/Indicators/unitymenumodelstack.cpp+9−100

This diff is too big to show here.

plugins/Unity/Indicators/unitymenumodelstack.h+3−11

This diff is too big to show here.

plugins/Unity/Indicators/visibleindicatorsmodel.cppnew file+92

This diff is too big to show here.

plugins/Unity/Indicators/visibleindicatorsmodel.hnew file+56

This diff is too big to show here.

plugins/Unity/InputInfo/CMakeLists.txtdeleted−38

This diff is too big to show here.

plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cppdeleted−296

This diff is too big to show here.

plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.hdeleted−96

This diff is too big to show here.

plugins/Unity/InputInfo/plugin.cppdeleted−32

This diff is too big to show here.

plugins/Unity/InputInfo/qdeclarativeinputdevicemodel.cppdeleted−196

This diff is too big to show here.

plugins/Unity/InputInfo/qdeclarativeinputdevicemodel_p.hdeleted−102

This diff is too big to show here.

plugins/Unity/InputInfo/qinputinfo.cppdeleted−270

This diff is too big to show here.

plugins/Unity/InputInfo/qinputinfo.hdeleted−142

This diff is too big to show here.

plugins/Unity/InputInfo/qmldirdeleted−3

This diff is too big to show here.

plugins/Unity/Launcher/CMakeLists.txt+12−29

This diff is too big to show here.

plugins/Unity/Launcher/appdrawermodel.cppdeleted−192

This diff is too big to show here.

plugins/Unity/Launcher/appdrawermodel.hdeleted−64

This diff is too big to show here.

plugins/Unity/Launcher/asadapter.cppdeleted−67

This diff is too big to show here.

plugins/Unity/Launcher/asadapter.hdeleted−46

This diff is too big to show here.

plugins/Unity/Launcher/backend/launcherbackend.cppnew file+320

This diff is too big to show here.

plugins/Unity/Launcher/backend/launcherbackend.hnew file+148

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/quicklistentry.cpp → plugins/Unity/Launcher/common/quicklistentry.cpprenamed+4−1

This diff is too big to show here.

plugins/Greeter/Unity/Launcher/quicklistentry.h → plugins/Unity/Launcher/common/quicklistentry.hrenamed+4−1

This diff is too big to show here.

plugins/Unity/Launcher/dbusinterface.cppdeleted−226

This diff is too big to show here.

plugins/Unity/Launcher/dbusinterface.hdeleted−49

This diff is too big to show here.

plugins/Unity/Launcher/gsettings.cppdeleted−80

This diff is too big to show here.

plugins/Unity/Launcher/gsettings.hdeleted−47

This diff is too big to show here.

plugins/Unity/Launcher/launcheritem.cpp+6−135

This diff is too big to show here.

plugins/Unity/Launcher/launcheritem.h+22−36

This diff is too big to show here.

plugins/Unity/Launcher/launchermodel.cpp+67−365

This diff is too big to show here.

plugins/Unity/Launcher/launchermodel.h+25−41

This diff is too big to show here.

plugins/Unity/Launcher/plugin.cpp+6−7

This diff is too big to show here.

plugins/Unity/Launcher/plugin.h+1−1

This diff is too big to show here.

plugins/Unity/Launcher/qmldir+1−1

This diff is too big to show here.

plugins/Unity/Launcher/quicklistentry.cppdeleted−85

This diff is too big to show here.

plugins/Unity/Launcher/quicklistentry.hdeleted−56

This diff is too big to show here.

plugins/Unity/Launcher/quicklistmodel.cpp+1−23

This diff is too big to show here.

plugins/Unity/Launcher/quicklistmodel.h+4−7

This diff is too big to show here.

plugins/Unity/Launcher/ualwrapper.cppdeleted−74

This diff is too big to show here.

plugins/Unity/Launcher/ualwrapper.hdeleted−36

This diff is too big to show here.

plugins/Unity/Launcher/xdgwatcher.cppdeleted−129

This diff is too big to show here.

plugins/Unity/Launcher/xdgwatcher.hdeleted−46

This diff is too big to show here.

plugins/Unity/Platform/CMakeLists.txtdeleted−11

This diff is too big to show here.

plugins/Unity/Platform/platform.cppdeleted−66

This diff is too big to show here.

plugins/Unity/Platform/platform.hdeleted−64

This diff is too big to show here.

plugins/Unity/Platform/qmldirdeleted−2

This diff is too big to show here.

plugins/Unity/Session/CMakeLists.txtdeleted−29

This diff is too big to show here.

plugins/Unity/Session/dbusunitysessionservice.cppdeleted−647

This diff is too big to show here.

plugins/Unity/Session/dbusunitysessionservice.hdeleted−377

This diff is too big to show here.

plugins/Unity/Session/orientationlock.cppdeleted−74

This diff is too big to show here.

plugins/Unity/Session/orientationlock.hdeleted−60

This diff is too big to show here.

plugins/Unity/Session/plugin.cppdeleted−48

This diff is too big to show here.

plugins/Unity/Session/qmldirdeleted−3

This diff is too big to show here.

plugins/Unity/abstractfilteroption.cppnew file+25

This diff is too big to show here.

plugins/Unity/abstractfilteroption.hnew file+58

This diff is too big to show here.

plugins/Unity/applicationpreview.cppnew file+100

This diff is too big to show here.

plugins/Unity/applicationpreview.hnew file+66

This diff is too big to show here.

plugins/Unity/bottombarvisibilitycommunicatorshell.cppnew file+49

This diff is too big to show here.

plugins/Unity/bottombarvisibilitycommunicatorshell.hnew file+59

This diff is too big to show here.

plugins/Unity/categories.cppnew file+299

This diff is too big to show here.

plugins/Unity/categories.hnew file+95

This diff is too big to show here.

plugins/Unity/categoryresults.cppnew file+121

This diff is too big to show here.

plugins/Unity/categoryresults.hnew file+68

This diff is too big to show here.

plugins/Unity/checkoptionfilter.cppnew file+65

This diff is too big to show here.

plugins/Unity/checkoptionfilter.hnew file+57

This diff is too big to show here.

plugins/Unity/filter.cppnew file+129

This diff is too big to show here.

plugins/Unity/filter.hnew file+75

This diff is too big to show here.

plugins/Unity/filteroption.cppnew file+91

This diff is too big to show here.

plugins/Unity/filteroption.hnew file+61

This diff is too big to show here.

plugins/Unity/filters.cppnew file+165

This diff is too big to show here.

plugins/Unity/filters.hnew file+77

This diff is too big to show here.

plugins/Unity/genericoptionsmodel.cppnew file+187

This diff is too big to show here.

plugins/Unity/genericoptionsmodel.hnew file+79

This diff is too big to show here.

tests/mocks/QMenuModel/UnityMenuAction.qml → plugins/Unity/genericpreview.cpprenamed+12−11

This diff is too big to show here.

tests/mocks/SessionBroadcast/SessionBroadcast.h → plugins/Unity/genericpreview.hrenamed+19−12

This diff is too big to show here.

plugins/Unity/iconutils.cppnew file+124

This diff is too big to show here.

tests/mocks/Biometryd/MockObserver.h → plugins/Unity/iconutils.hrenamed+9−17

This diff is too big to show here.

plugins/Unity/moviepreview.cppnew file+67

This diff is too big to show here.

plugins/Unity/moviepreview.hnew file+60

This diff is too big to show here.

plugins/Unity/multirangefilter.cppnew file+65

This diff is too big to show here.

plugins/Unity/multirangefilter.hnew file+60

This diff is too big to show here.

plugins/Unity/musicpreview.cppnew file+54

This diff is too big to show here.

plugins/Unity/musicpreview.hnew file+62

This diff is too big to show here.

plugins/Unity/plugin.cppnew file+74

This diff is too big to show here.

plugins/Unity/Session/plugin.h → plugins/Unity/plugin.hrenamed+7−6

This diff is too big to show here.

plugins/Unity/preview.cppnew file+199

This diff is too big to show here.

plugins/Unity/preview.hnew file+89

This diff is too big to show here.

plugins/Unity/previewaction.cppnew file+75

This diff is too big to show here.

plugins/Unity/previewaction.hnew file+71

This diff is too big to show here.

plugins/Unity/previewinfohint.cppnew file+67

This diff is too big to show here.

plugins/Unity/previewinfohint.hnew file+58

This diff is too big to show here.

plugins/Unity/qmldirnew file+3

This diff is too big to show here.

plugins/Unity/radiooptionfilter.cppnew file+61

This diff is too big to show here.

plugins/Unity/radiooptionfilter.hnew file+59

This diff is too big to show here.

plugins/Unity/ratingfilteroption.cppnew file+62

This diff is too big to show here.

plugins/Unity/ratingfilteroption.hnew file+53

This diff is too big to show here.

plugins/Unity/ratingoptionsmodel.cppnew file+33

This diff is too big to show here.

plugins/Unity/ratingoptionsmodel.hnew file+33

This diff is too big to show here.

plugins/Unity/ratingsfilter.cppnew file+73

This diff is too big to show here.

plugins/Unity/ratingsfilter.hnew file+66

This diff is too big to show here.

plugins/Unity/result.cppnew file+82

This diff is too big to show here.

plugins/Unity/result.hnew file+69

This diff is too big to show here.

plugins/Unity/scope.cppnew file+413

This diff is too big to show here.

plugins/Unity/scope.hnew file+154

This diff is too big to show here.

plugins/Unity/scopes.cppnew file+176

This diff is too big to show here.

plugins/Unity/scopes.hnew file+94

This diff is too big to show here.

plugins/Unity/showallfilteroption.cppnew file+60

This diff is too big to show here.

tests/mocks/QMenuModel/actiondata.h → plugins/Unity/showallfilteroption.hrenamed+26−29

This diff is too big to show here.

plugins/Unity/signalslist.cppnew file+39

This diff is too big to show here.

plugins/Unity/signalslist.hnew file+38

This diff is too big to show here.

plugins/Unity/socialpreview.cppnew file+87

This diff is too big to show here.

plugins/Unity/socialpreview.hnew file+63

This diff is too big to show here.

plugins/Unity/socialpreviewcomment.cppnew file+63

This diff is too big to show here.

plugins/Unity/socialpreviewcomment.hnew file+57

This diff is too big to show here.

plugins/Unity/unityoptionsmodel.cppnew file+68

This diff is too big to show here.

plugins/Unity/unityoptionsmodel.hnew file+50

This diff is too big to show here.

plugins/Unity/variantutils.cppnew file+82

This diff is too big to show here.

plugins/Unity/variantutils.hnew file+35

This diff is too big to show here.

plugins/Utils/CMakeLists.txt+17−33

This diff is too big to show here.

plugins/Utils/EdgeBarrierSettings.qmldeleted−66

This diff is too big to show here.

plugins/Utils/ElapsedTimer.hdeleted−51

This diff is too big to show here.

plugins/Utils/Style.jsdeleted−37

This diff is too big to show here.

plugins/Utils/Timer.cppdeleted−62

This diff is too big to show here.

plugins/Utils/Timer.hdeleted−78

This diff is too big to show here.

plugins/Utils/URLDispatcher.cppdeleted−80

This diff is too big to show here.

plugins/Utils/URLDispatcher.hdeleted−47

This diff is too big to show here.

plugins/Utils/WindowInputMonitor.cppdeleted−126

This diff is too big to show here.

plugins/Utils/WindowInputMonitor.hdeleted−97

This diff is too big to show here.

plugins/Utils/activefocuslogger.cppdeleted−61

This diff is too big to show here.

plugins/Utils/activefocuslogger.hdeleted−37

This diff is too big to show here.

plugins/Utils/albumartprovider.cppnew file+231

This diff is too big to show here.

plugins/Utils/albumartprovider.hnew file+56

This diff is too big to show here.

plugins/Utils/appdrawerproxymodel.cppdeleted−189

This diff is too big to show here.

plugins/Utils/appdrawerproxymodel.hdeleted−87

This diff is too big to show here.

plugins/Utils/applicationpaths.hnew file+38

This diff is too big to show here.

plugins/Utils/applicationsfiltermodel.cppdeleted−101

This diff is too big to show here.

plugins/Utils/applicationsfiltermodel.hdeleted−69

This diff is too big to show here.

plugins/Utils/constants.cppdeleted−32

This diff is too big to show here.

plugins/Utils/constants.hdeleted−43

This diff is too big to show here.

plugins/Utils/deviceconfigparser.cppdeleted−176

This diff is too big to show here.

plugins/Utils/deviceconfigparser.hdeleted−66

This diff is too big to show here.

plugins/Utils/easingcurve.cppdeleted−73

This diff is too big to show here.

plugins/Utils/easingcurve.hdeleted−69

This diff is too big to show here.

plugins/Utils/expressionfiltermodel.cppdeleted−49

This diff is too big to show here.

plugins/Utils/expressionfiltermodel.hdeleted−42

This diff is too big to show here.

plugins/Utils/globalfunctions.cppdeleted−58

This diff is too big to show here.

plugins/Utils/globalfunctions.hdeleted−44

This diff is too big to show here.

plugins/Utils/inputeventgenerator.cppdeleted−34

This diff is too big to show here.

plugins/Utils/inputeventgenerator.hdeleted−40

This diff is too big to show here.

plugins/Utils/inputwatcher.cppdeleted−118

This diff is too big to show here.

plugins/Utils/inputwatcher.hdeleted−58

This diff is too big to show here.

plugins/Utils/mediaartcache.cppnew file+178

This diff is too big to show here.

plugins/Utils/mediaartcache.hnew file+54

This diff is too big to show here.

plugins/Utils/plugin.cpp+33−59

This diff is too big to show here.

plugins/Utils/plugin.h+2−1

This diff is too big to show here.

plugins/Utils/qlimitproxymodelqml.cpp+17−17

This diff is too big to show here.

plugins/Utils/qlimitproxymodelqml.h+2−2

This diff is too big to show here.

plugins/Utils/qmldir+1−3

This diff is too big to show here.

plugins/Wizard/Utils/qsortfilterproxymodelqml.cpp → plugins/Utils/qsortfilterproxymodelqml.cpprenamed−12

This diff is too big to show here.

plugins/Wizard/Utils/qsortfilterproxymodelqml.h → plugins/Utils/qsortfilterproxymodelqml.hrenamed−1

This diff is too big to show here.

plugins/Utils/quicklistproxymodel.cppdeleted−72

This diff is too big to show here.

plugins/Utils/quicklistproxymodel.hdeleted−52

This diff is too big to show here.

plugins/Utils/qvariantlistmodel.h+6−6

This diff is too big to show here.

plugins/Utils/tabfocusfence.cppdeleted−72

This diff is too big to show here.

plugins/Utils/tabfocusfence.hdeleted−38

This diff is too big to show here.

plugins/Utils/timezoneFormatter.cppdeleted−45

This diff is too big to show here.

plugins/Utils/timezoneFormatter.hdeleted−33

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.cpp → plugins/Utils/ubuntuwindow.cpprenamed+11−10

This diff is too big to show here.

plugins/Lights/LegacyLights.h → plugins/Utils/ubuntuwindow.hrenamed+15−18

This diff is too big to show here.

plugins/Utils/unitysortfilterproxymodelqml.cppdeleted−167

This diff is too big to show here.

plugins/Utils/unitysortfilterproxymodelqml.hdeleted−68

This diff is too big to show here.

plugins/Utils/windowinputfilter.cppdeleted−70

This diff is too big to show here.

plugins/Utils/windowinputfilter.hdeleted−58

This diff is too big to show here.

plugins/Utils/windowstatestorage.cppdeleted−383

This diff is too big to show here.

plugins/Utils/windowstatestorage.hdeleted−74

This diff is too big to show here.

plugins/WindowManager/AvailableDesktopArea.cppdeleted−50

This diff is too big to show here.

plugins/WindowManager/AvailableDesktopArea.hdeleted−38

This diff is too big to show here.

plugins/WindowManager/CMakeLists.txtdeleted−26

This diff is too big to show here.

plugins/WindowManager/InputMethodManager.cppdeleted−56

This diff is too big to show here.

plugins/WindowManager/InputMethodManager.hdeleted−55

This diff is too big to show here.

plugins/WindowManager/TopLevelWindowModel.cppdeleted−782

This diff is too big to show here.

plugins/WindowManager/TopLevelWindowModel.hdeleted−308

This diff is too big to show here.

plugins/WindowManager/Window.cppdeleted−277

This diff is too big to show here.

plugins/WindowManager/Window.hdeleted−176

This diff is too big to show here.

plugins/WindowManager/WindowManagerGlobal.hdeleted−23

This diff is too big to show here.

plugins/WindowManager/WindowManagerPlugin.cppdeleted−44

This diff is too big to show here.

plugins/WindowManager/WindowManagerPlugin.hdeleted−32

This diff is too big to show here.

plugins/WindowManager/WindowMargins.cppdeleted−74

This diff is too big to show here.

plugins/WindowManager/WindowMargins.hdeleted−59

This diff is too big to show here.

plugins/WindowManager/qmldirdeleted−2

This diff is too big to show here.

plugins/Wizard/50-com.canonical.unity.wizard.pkladeleted−6

This diff is too big to show here.

plugins/Wizard/CMakeLists.txtdeleted−23

This diff is too big to show here.

plugins/Wizard/Changelog.cppdeleted−58

This diff is too big to show here.

plugins/Wizard/Changelog.hdeleted−52

This diff is too big to show here.

plugins/Wizard/LocalePlugin.cppdeleted−291

This diff is too big to show here.

plugins/Wizard/LocalePlugin.hdeleted−58

This diff is too big to show here.

plugins/Wizard/PageList.cppdeleted−127

This diff is too big to show here.

plugins/Wizard/PageList.hdeleted−53

This diff is too big to show here.

plugins/Wizard/Status.cppdeleted−143

This diff is too big to show here.

plugins/Wizard/Status.hdeleted−60

This diff is too big to show here.

plugins/Wizard/System.cppdeleted−182

This diff is too big to show here.

plugins/Wizard/System.hdeleted−75

This diff is too big to show here.

plugins/Wizard/Unity/Application/CMakeLists.txtdeleted−3

This diff is too big to show here.

plugins/Wizard/Unity/Application/qmldirdeleted−2

This diff is too big to show here.

plugins/Wizard/Unity/CMakeLists.txtdeleted−1

This diff is too big to show here.

plugins/Wizard/Utils/CMakeLists.txtdeleted−27

This diff is too big to show here.

plugins/Wizard/Utils/plugin.cppdeleted−41

This diff is too big to show here.

plugins/Wizard/Utils/qmldirdeleted−2

This diff is too big to show here.

plugins/Wizard/keyboardLayoutsModel.cppdeleted−163

This diff is too big to show here.

plugins/Wizard/keyboardLayoutsModel.hdeleted−66

This diff is too big to show here.

plugins/Wizard/main.cppdeleted−93

This diff is too big to show here.

plugins/Wizard/plugin.cppdeleted−38

This diff is too big to show here.

plugins/Wizard/plugin.hdeleted−31

This diff is too big to show here.

plugins/Wizard/qmldirdeleted−2

This diff is too big to show here.

plugins/Wizard/timezonemodel.cppdeleted−244

This diff is too big to show here.

plugins/Wizard/timezonemodel.hdeleted−80

This diff is too big to show here.

plugins/Wizard/ubuntu-system-settings-wizard-cleanup.confdeleted−20

This diff is too big to show here.

plugins/Wizard/ubuntu-system-settings-wizard-set-lang.confdeleted−30

This diff is too big to show here.

plugins/Wizard/ubuntu-system-settings-wizard.confdeleted−75

This diff is too big to show here.

po/aa.podeleted−880

This diff is too big to show here.

po/am.podeleted−1406

This diff is too big to show here.

po/ar.po+169−1200

This diff is too big to show here.

po/ast.po+173−1333

This diff is too big to show here.

po/az.po+121−860

This diff is too big to show here.

po/be.podeleted−1253

This diff is too big to show here.

po/bg.po+135−781

This diff is too big to show here.

po/bn.podeleted−1062

This diff is too big to show here.

po/br.podeleted−1348

This diff is too big to show here.

po/bs.podeleted−1146

This diff is too big to show here.

po/ca.po+173−1379

This diff is too big to show here.

po/ca@valencia.podeleted−1125

This diff is too big to show here.

po/ce.podeleted−816

This diff is too big to show here.

po/ckb.podeleted−870

This diff is too big to show here.

po/co.podeleted−1061

This diff is too big to show here.

po/cs.po+167−1260

This diff is too big to show here.

po/cy.podeleted−1165

This diff is too big to show here.

po/da.podeleted−1216

This diff is too big to show here.

po/de.po+159−1384

This diff is too big to show here.

po/el.po+151−1255

This diff is too big to show here.

po/en_AU.po+169−1368

This diff is too big to show here.

po/en_GB.po+162−1322

This diff is too big to show here.

po/en_US.podeleted−814

This diff is too big to show here.

po/eo.po+110−811

This diff is too big to show here.

po/es.po+174−1367

This diff is too big to show here.

po/et.podeleted−816

This diff is too big to show here.

po/eu.podeleted−1246

This diff is too big to show here.

po/fa.po+144−1374

This diff is too big to show here.

po/fi.po+172−1363

This diff is too big to show here.

po/fo.po+130−811

This diff is too big to show here.

po/fr.po+150−1393

This diff is too big to show here.

po/ga.podeleted−1109

This diff is too big to show here.

po/gd.po+177−1385

This diff is too big to show here.

po/gl.po+170−1362

This diff is too big to show here.

po/gu.podeleted−814

This diff is too big to show here.

po/gv.podeleted−918

This diff is too big to show here.

po/he.po+171−1017

This diff is too big to show here.

po/hi.podeleted−850

This diff is too big to show here.

po/hr.po+157−1309

This diff is too big to show here.

po/hu.po+156−1363

This diff is too big to show here.

po/hy.po+126−848

This diff is too big to show here.

po/ia.podeleted−1409

This diff is too big to show here.

po/id.po+110−895

This diff is too big to show here.

po/is.po+167−921

This diff is too big to show here.

po/it.po+175−1373

This diff is too big to show here.

po/ja.po+114−903

This diff is too big to show here.

po/kk.podeleted−841

This diff is too big to show here.

po/km.po+172−995

This diff is too big to show here.

po/kn.po+117−720

This diff is too big to show here.

po/ko.po+156−1175

This diff is too big to show here.

po/ku.podeleted−978

This diff is too big to show here.

po/ky.po+117−720

This diff is too big to show here.

po/lo.po+134−739

This diff is too big to show here.

po/lt.podeleted−1034

This diff is too big to show here.

po/lv.po+141−1113

This diff is too big to show here.

po/ml.podeleted−871

This diff is too big to show here.

po/mr.podeleted−864

This diff is too big to show here.

po/ms.podeleted−1376

This diff is too big to show here.

po/my.po+151−818

This diff is too big to show here.

po/nb.po+158−1354

This diff is too big to show here.

po/ne.podeleted−834

This diff is too big to show here.

po/nl.po+157−1365

This diff is too big to show here.

po/nn.podeleted−816

This diff is too big to show here.

po/oc.podeleted−1276

This diff is too big to show here.

po/or.podeleted−816

This diff is too big to show here.

po/pa.podeleted−1153

This diff is too big to show here.

po/pl.po+160−1362

This diff is too big to show here.

po/pt.podeleted−1435

This diff is too big to show here.

po/pt_BR.po+170−1156

This diff is too big to show here.

po/ro.po+122−1144

This diff is too big to show here.

po/ru.po+174−1363

This diff is too big to show here.

po/sc.podeleted−904

This diff is too big to show here.

po/shn.po+108−701

This diff is too big to show here.

po/si.po+109−771

This diff is too big to show here.

po/sk.podeleted−1352

This diff is too big to show here.

po/sl.po+179−1331

This diff is too big to show here.

po/sq.podeleted−1048

This diff is too big to show here.

po/sr.po+146−1329

This diff is too big to show here.

po/sv.po+155−1363

This diff is too big to show here.

po/sw.podeleted−1087

This diff is too big to show here.

po/ta.po+159−802

This diff is too big to show here.

po/te.po+110−753

This diff is too big to show here.

po/th.po+112−709

This diff is too big to show here.

po/tr.po+169−1352

This diff is too big to show here.

po/ug.po+156−1184

This diff is too big to show here.

po/uk.po+161−1365

This diff is too big to show here.

po/unity8.pot+105−697

This diff is too big to show here.

po/update-unity-pot+5−31

This diff is too big to show here.

po/ur.podeleted−819

This diff is too big to show here.

po/uz.podeleted−816

This diff is too big to show here.

po/vi.podeleted−816

This diff is too big to show here.

po/wo.podeleted−1232

This diff is too big to show here.

po/xh.po+106−699

This diff is too big to show here.

po/zh_CN.po+170−1306

This diff is too big to show here.

po/zh_HK.podeleted−897

This diff is too big to show here.

po/zh_TW.po+161−1259

This diff is too big to show here.

qml/ApplicationMenus/ApplicationMenuItemFactory.qmldeleted−135

This diff is too big to show here.

qml/ApplicationMenus/ApplicationMenusLimits.qmldeleted−24

This diff is too big to show here.

qml/ApplicationMenus/MenuBar.qmldeleted−513

This diff is too big to show here.

qml/ApplicationMenus/MenuItem.qmldeleted−146

This diff is too big to show here.

qml/ApplicationMenus/MenuNavigator.qmldeleted−101

This diff is too big to show here.

qml/ApplicationMenus/MenuPopup.qmldeleted−510

This diff is too big to show here.

qml/ApplicationMenus/RegisteredApplicationMenuModel.qmldeleted−56

This diff is too big to show here.

qml/ApplicationMenus/qmldirdeleted−1

This diff is too big to show here.

qml/CMakeLists.txtdeleted−23

This diff is too big to show here.

qml/Components/Background.qmldeleted−87

This diff is too big to show here.

qml/Components/BlurLayer.qmldeleted−39

This diff is too big to show here.

qml/Components/BrightnessControl.qmldeleted−54

This diff is too big to show here.

qml/Components/Dialogs.qmldeleted−328

This diff is too big to show here.

qml/Components/EdgeBarrier.qmldeleted−114

This diff is too big to show here.

qml/Components/EdgeBarrierController.qmldeleted−74

This diff is too big to show here.

qml/Components/FadingLabel.qmldeleted−42

This diff is too big to show here.

qml/Components/Flickable.qmldeleted−24

This diff is too big to show here.

qml/Components/FloatingFlickable.qmldeleted−63

This diff is too big to show here.

qml/Components/GridView.qmldeleted−24

This diff is too big to show here.

qml/Components/Handle.qmldeleted−44

This diff is too big to show here.

qml/Components/InputMethod.qmldeleted−58

This diff is too big to show here.

qml/Components/ItemGrabber.qmldeleted−86

This diff is too big to show here.

qml/Components/KeyboardShortcutsOverlay.qmldeleted−336

This diff is too big to show here.

qml/Components/KeymapSwitcher.qmldeleted−102

This diff is too big to show here.

qml/Components/ListView.qmldeleted−24

This diff is too big to show here.

qml/Components/ListViewOSKScroller.qmldeleted−53

This diff is too big to show here.

qml/Components/Lockscreen.qmldeleted−256

This diff is too big to show here.

qml/Components/MediaServices/MediaServices.qmldeleted−386

This diff is too big to show here.

qml/Components/MediaServices/MediaServicesControls.qmldeleted−192

This diff is too big to show here.

qml/Components/MediaServices/MediaServicesHeader.qmldeleted−71

This diff is too big to show here.

qml/Components/MediaServices/VideoPlayer.qmldeleted−155

This diff is too big to show here.

qml/Components/MediaServices/VideoPlayerControls.qmldeleted−158

This diff is too big to show here.

qml/Components/ModeSwitchWarningDialog.qmldeleted−101

This diff is too big to show here.

qml/Components/NotificationAudio.qmldeleted−60

This diff is too big to show here.

qml/Components/Orientations.qmldeleted−57

This diff is too big to show here.

qml/Components/PanelState/PanelState.qmldeleted−36

This diff is too big to show here.

qml/Components/PanelState/qmldirdeleted−1

This diff is too big to show here.

qml/Components/PassphraseLockscreen.qmldeleted−150

This diff is too big to show here.

qml/Components/PhysicalKeysMapper.qmldeleted−163

This diff is too big to show here.

qml/Components/PinLockscreen.qmldeleted−258

This diff is too big to show here.

qml/Components/PinPadButton.qmldeleted−78

This diff is too big to show here.

qml/Components/Rating.qmldeleted−49

This diff is too big to show here.

qml/Components/RatingStyle.qmldeleted−50

This diff is too big to show here.

qml/Components/ScrollCalculator.qmldeleted−100

This diff is too big to show here.

qml/Components/SearchHistoryModel/qmldirdeleted−1

This diff is too big to show here.

qml/Components/SharingPicker.qmldeleted−102

This diff is too big to show here.

qml/Components/ShellDialog.qmldeleted−68

This diff is too big to show here.

qml/Components/VirtualTouchPad.qmldeleted−406

This diff is too big to show here.

qml/Components/VolumeControl.qmldeleted−63

This diff is too big to show here.

qml/Components/Wallpaper.qmldeleted−96

This diff is too big to show here.

qml/Components/WallpaperResolver.qmldeleted−60

This diff is too big to show here.

qml/Components/WindowControlButtons.qmldeleted−121

This diff is too big to show here.

qml/Components/ZoomableImage.qmldeleted−157

This diff is too big to show here.

qml/Components/flickableUtils.jsdeleted−28

This diff is too big to show here.

qml/Components/graphics/close@20.pngdeleted

Binary file not shown.

qml/Components/graphics/icon_star_empty@20.pngdeleted

Binary file not shown.

qml/Components/graphics/icon_star_full@20.pngdeleted

Binary file not shown.

qml/Components/graphics/icon_star_half@20.pngdeleted

Binary file not shown.

qml/Components/graphics/icon_star_off@20.pngdeleted

Binary file not shown.

qml/Components/graphics/icon_star_on@20.pngdeleted

Binary file not shown.

qml/Components/graphics/non-selected@18.pngdeleted

Binary file not shown.

qml/Components/graphics/window-close.svgdeleted−164

This diff is too big to show here.

qml/Components/graphics/window-maximize.svgdeleted−164

This diff is too big to show here.

qml/Components/graphics/window-minimize.svgdeleted−164

This diff is too big to show here.

qml/Components/graphics/window-window.svgdeleted−41

This diff is too big to show here.

qml/DeviceConfiguration.qmldeleted−161

This diff is too big to show here.

qml/DisabledScreenNotice.qmldeleted−81

This diff is too big to show here.

qml/Greeter/ButtonPrompt.qmldeleted−51

This diff is too big to show here.

qml/Greeter/Circle.qmldeleted−57

This diff is too big to show here.

qml/Greeter/CoverPage.qmldeleted−271

This diff is too big to show here.

qml/Greeter/DelayedLockscreen.qmldeleted−86

This diff is too big to show here.

qml/Greeter/FullLightDMImpl.qmldeleted−31

This diff is too big to show here.

qml/Greeter/Greeter.qmldeleted−632

This diff is too big to show here.

qml/Greeter/GreeterPrompt.qmldeleted−127

This diff is too big to show here.

qml/Greeter/GreeterView.qmldeleted−534

This diff is too big to show here.

qml/Greeter/IntegratedLightDMImpl.qmldeleted−30

This diff is too big to show here.

qml/Greeter/LightDMService.qmldeleted−54

This diff is too big to show here.

qml/Greeter/LoginList.qmldeleted−292

This diff is too big to show here.

qml/Greeter/PinPrompt.qmldeleted−184

This diff is too big to show here.

qml/Greeter/PromptList.qmldeleted−151

This diff is too big to show here.

qml/Greeter/SessionIcon.qmldeleted−47

This diff is too big to show here.

qml/Greeter/SessionsList.qmldeleted−205

This diff is too big to show here.

qml/Greeter/ShimGreeter.qmldeleted−47

This diff is too big to show here.

qml/Greeter/TextPrompt.qmldeleted−198

This diff is too big to show here.

qml/Greeter/graphics/dot_empty.pngdeleted

Binary file not shown.

qml/Greeter/graphics/dot_filled.pngdeleted

Binary file not shown.

qml/Greeter/graphics/dot_pointer.pngdeleted

Binary file not shown.

qml/Greeter/graphics/icon_arrow.pngdeleted

Binary file not shown.

qml/Greeter/graphics/session_icons/gnome_badge.pngdeleted

Binary file not shown.

qml/Greeter/graphics/session_icons/kde_badge.pngdeleted

Binary file not shown.

qml/Greeter/graphics/session_icons/recovery_console_badge.pngdeleted

Binary file not shown.

qml/Greeter/graphics/session_icons/ubuntu_badge.pngdeleted

Binary file not shown.

qml/Greeter/graphics/session_icons/unknown_badge.pngdeleted

Binary file not shown.

qml/Greeter/qmldirdeleted−1

This diff is too big to show here.

qml/Launcher/BackgroundBlur.qmldeleted−81

This diff is too big to show here.

qml/Launcher/Drawer.qmldeleted−413

This diff is too big to show here.

qml/Launcher/DrawerGridView.qmldeleted−85

This diff is too big to show here.

qml/Launcher/Launcher.qmldeleted−661

This diff is too big to show here.

qml/Launcher/LauncherPanel.qmldeleted−961

This diff is too big to show here.

qml/Launcher/PullToRefreshScopeStyle.qmldeleted−83

This diff is too big to show here.

qml/Launcher/Tooltip.qmldeleted−72

This diff is too big to show here.

qml/Launcher/graphics/divider-line.pngdeleted

Binary file not shown.

qml/Launcher/graphics/focused_app_arrow@30.pngdeleted

Binary file not shown.

qml/Launcher/graphics/home.svgdeleted−243

This diff is too big to show here.

qml/Launcher/graphics/quicklist_tooltip@30.pngdeleted

Binary file not shown.

qml/Notifications/Notification.qmldeleted−600

This diff is too big to show here.

qml/Notifications/NotificationButton.qmldeleted−73

This diff is too big to show here.

qml/Notifications/NotificationMenuItemFactory.qmldeleted−230

This diff is too big to show here.

qml/Notifications/Notifications.qmldeleted−115

This diff is too big to show here.

qml/Notifications/OptionToggle.qmldeleted−125

This diff is too big to show here.

qml/Notifications/ShapedIcon.qmldeleted−43

This diff is too big to show here.

qml/Notifications/SwipeToAct.qmldeleted−275

This diff is too big to show here.

qml/OrientedShell.qmldeleted−336

This diff is too big to show here.

qml/Panel/ActiveCallHint.qmldeleted−211

This diff is too big to show here.

qml/Panel/Indicators/IndicatorItem.qmldeleted−310

This diff is too big to show here.

qml/Panel/Indicators/IndicatorMenuItemFactory.qmldeleted−1113

This diff is too big to show here.

qml/Panel/Indicators/IndicatorsLight.qmldeleted−234

This diff is too big to show here.

qml/Panel/Indicators/MessageMenuItemFactory.qmldeleted−244

This diff is too big to show here.

qml/Panel/Indicators/client/IndicatorRepresentation.qmldeleted−121

This diff is too big to show here.

qml/Panel/MenuContent.qmldeleted−83

This diff is too big to show here.

qml/Panel/Panel.qmldeleted−522

This diff is too big to show here.

qml/Panel/PanelBar.qmldeleted−330

This diff is too big to show here.

qml/Panel/PanelItemRow.qmldeleted−270

This diff is too big to show here.

qml/Panel/PanelMenu.qmldeleted−414

This diff is too big to show here.

qml/Panel/PanelMenuPage.qmldeleted−226

This diff is too big to show here.

qml/Panel/PanelVelocityCalculator.qmldeleted−54

This diff is too big to show here.

qml/Panel/graphics/rectangular_dropshadow@30.pngdeleted

Binary file not shown.

qml/Rotation/HalfLoopRotationAnimation.qmldeleted−47

This diff is too big to show here.

qml/Rotation/ImmediateRotationAction.qmldeleted−34

This diff is too big to show here.

qml/Rotation/NinetyRotationAnimation.qmldeleted−88

This diff is too big to show here.

qml/Rotation/RotationStates.qmldeleted−289

This diff is too big to show here.

qml/Rotation/UpdateShellTransformations.qmldeleted−42

This diff is too big to show here.

qml/Shell.qmldeleted−951

This diff is too big to show here.

qml/Stage/ApplicationWindow.qmldeleted−416

This diff is too big to show here.

qml/Stage/ChildWindow.qmldeleted−203

This diff is too big to show here.

qml/Stage/ChildWindowRepeater.qmldeleted−39

This diff is too big to show here.

qml/Stage/ChildWindowTree.qmldeleted−138

This diff is too big to show here.

qml/Stage/DecoratedWindow.qmldeleted−319

This diff is too big to show here.

qml/Stage/FakeMaximizeDelegate.qmldeleted−233

This diff is too big to show here.

qml/Stage/MainViewStyle.qmldeleted−87

This diff is too big to show here.

qml/Stage/MoveHandler.qmldeleted−201

This diff is too big to show here.

qml/Stage/OrientationChangeAnimation.qmldeleted−265

This diff is too big to show here.

qml/Stage/PromptSurfaceAnimations.qmldeleted−80

This diff is too big to show here.

qml/Stage/SideStage.qmldeleted−121

This diff is too big to show here.

qml/Stage/Splash.qmldeleted−150

This diff is too big to show here.

qml/Stage/Spread/BezierCurve.qmldeleted−45

This diff is too big to show here.

qml/Stage/Spread/KeySpline.jsdeleted−66

This diff is too big to show here.

qml/Stage/Spread/MathUtils.jsdeleted−95

This diff is too big to show here.

qml/Stage/Spread/OpacityMask.qmldeleted−82

This diff is too big to show here.

qml/Stage/Spread/Spread.qmldeleted−173

This diff is too big to show here.

qml/Stage/Spread/SpreadDelegateInputArea.qmldeleted−189

This diff is too big to show here.

qml/Stage/Spread/SpreadMaths.qmldeleted−78

This diff is too big to show here.

qml/Stage/Spread/StagedRightEdgeMaths.qmldeleted−174

This diff is too big to show here.

qml/Stage/Spread/WindowedRightEdgeMaths.qmldeleted−96

This diff is too big to show here.

qml/Stage/Spread/cubic-bezier.jsdeleted−39

This diff is too big to show here.

qml/Stage/Stage.qmldeleted−2241

This diff is too big to show here.

qml/Stage/StageMaths.qmldeleted−93

This diff is too big to show here.

qml/Stage/StagedFullscreenPolicy.qmldeleted−50

This diff is too big to show here.

qml/Stage/SurfaceContainer.qmldeleted−108

This diff is too big to show here.

qml/Stage/TabletSideStageTouchGesture.qmldeleted−157

This diff is too big to show here.

qml/Stage/WindowControlsOverlay.qmldeleted−254

This diff is too big to show here.

qml/Stage/WindowDecoration.qmldeleted−163

This diff is too big to show here.

qml/Stage/WindowInfoItem.qmldeleted−69

This diff is too big to show here.

qml/Stage/WindowResizeArea.qmldeleted−300

This diff is too big to show here.

qml/Stage/WindowStateSaver.qmldeleted−64

This diff is too big to show here.

qml/Stage/WindowedFullscreenPolicy.qmldeleted−31

This diff is too big to show here.

qml/Stage/graphics/PageHeaderBaseDividerBottom@18.pngdeleted

Binary file not shown.

qml/Stage/graphics/PageHeaderBaseDividerLight@18.pngdeleted

Binary file not shown.

qml/Stage/graphics/PageHeaderBaseDividerLight@18.scideleted−5

This diff is too big to show here.

qml/Stage/graphics/arrows-centre.pngdeleted

Binary file not shown.

qml/Stage/graphics/arrows.pngdeleted

Binary file not shown.

qml/Stage/graphics/sidestage_drag.svgdeleted−207

This diff is too big to show here.

qml/Stage/graphics/sidestage_handle@20.pngdeleted

Binary file not shown.

qml/Stage/graphics/sidestage_open.svgdeleted−181

This diff is too big to show here.

qml/Stage/graphics/window-close.svgdeleted−64

This diff is too big to show here.

qml/Tutorial/InactivityTimer.qmldeleted−78

This diff is too big to show here.

qml/Tutorial/Tutorial.qmldeleted−105

This diff is too big to show here.

qml/Tutorial/TutorialContent.qmldeleted−225

This diff is too big to show here.

qml/Tutorial/TutorialLeft.qmldeleted−54

This diff is too big to show here.

qml/Tutorial/TutorialLeftLong.qmldeleted−56

This diff is too big to show here.

qml/Tutorial/TutorialPage.qmldeleted−121

This diff is too big to show here.

qml/Tutorial/TutorialRight.qmldeleted−61

This diff is too big to show here.

qml/Tutorial/TutorialTop.qmldeleted−60

This diff is too big to show here.

qml/Tutorial/graphics/arrow.svgdeleted−19

This diff is too big to show here.

qml/Tutorial/graphics/background1.pngdeleted

Binary file not shown.

qml/Tutorial/graphics/background2.pngdeleted

Binary file not shown.

qml/Wizard/CheckableSetting.qmldeleted−92

This diff is too big to show here.

qml/Wizard/Components/InputMethod.qmldeleted−113

This diff is too big to show here.

qml/Wizard/Page.qmldeleted−340

This diff is too big to show here.

qml/Wizard/Pages.qmldeleted−269

This diff is too big to show here.

qml/Wizard/Pages/10-welcome-update.qmldeleted−137

This diff is too big to show here.

qml/Wizard/Pages/10-welcome.qmldeleted−197

This diff is too big to show here.

qml/Wizard/Pages/11-changelog.qmldeleted−95

This diff is too big to show here.

qml/Wizard/Pages/20-keyboard.qmldeleted−161

This diff is too big to show here.

qml/Wizard/Pages/30-wifi.qmldeleted−219

This diff is too big to show here.

qml/Wizard/Pages/50-timezone.qmldeleted−278

This diff is too big to show here.

qml/Wizard/Pages/60-account.qmldeleted−76

This diff is too big to show here.

qml/Wizard/Pages/70-passwd-type.qmldeleted−168

This diff is too big to show here.

qml/Wizard/Pages/78-firmware-update.qml.disableddeleted−246

This diff is too big to show here.

qml/Wizard/Pages/79-system-update.qmldeleted−148

This diff is too big to show here.

qml/Wizard/Pages/80-finished.qmldeleted−137

This diff is too big to show here.

qml/Wizard/Pages/data/Desktop_header_bkg.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/Desktop_splash_screen_bkg.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/Phone_header_bkg.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/Phone_splash_screen_bkg.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/Tick@30.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/map.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/pin.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-1.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-10.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-11.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-2.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-3.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-3.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-4.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-4.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-6.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-7.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-8.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-9.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_-9.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_0.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_1.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_10.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_10.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_11.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_12.75.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_12.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_13.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_2.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_3.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_3.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_4.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_4.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_5.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_5.75.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_6.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_6.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_7.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_8.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_8.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_9.5.pngdeleted

Binary file not shown.

qml/Wizard/Pages/data/timezonemap/timezone_9.pngdeleted

Binary file not shown.

qml/Wizard/Pages/passcode-confirm.qmldeleted−69

This diff is too big to show here.

qml/Wizard/Pages/passcode-desktop.qmldeleted−159

This diff is too big to show here.

qml/Wizard/Pages/passcode-set.qmldeleted−78

This diff is too big to show here.

qml/Wizard/Pages/password-set.qmldeleted−158

This diff is too big to show here.

qml/Wizard/Pages/sim.qmldeleted−108

This diff is too big to show here.

qml/Wizard/PasswordMeter.qmldeleted−108

This diff is too big to show here.

qml/Wizard/Wizard.qmldeleted−58

This diff is too big to show here.

qml/Wizard/WizardItemSelector.qmldeleted−129

This diff is too big to show here.

qml/graphics/dropshadow2gu@30.pngdeleted

Binary file not shown.

qml/graphics/dropshadow2gu@30.scideleted−5

This diff is too big to show here.

qml/graphics/dropshadow_left@20.pngdeleted

Binary file not shown.

qml/graphics/dropshadow_right@20.pngdeleted

Binary file not shown.

runnew file+72

This diff is too big to show here.

run_on_devicenew file+166

This diff is too big to show here.

runtests.sh+14−5

This diff is too big to show here.

src/ApplicationArguments.hdeleted−58

This diff is too big to show here.

src/CMakeLists.txt+1−64

This diff is too big to show here.

src/CachingNetworkManagerFactory.cppdeleted−54

This diff is too big to show here.

src/CachingNetworkManagerFactory.hdeleted−47

This diff is too big to show here.

src/DebuggingController.cppdeleted−92

This diff is too big to show here.

src/DebuggingController.hdeleted−57

This diff is too big to show here.

src/MouseTouchAdaptor.cppdeleted−419

This diff is too big to show here.

src/Panel/CMakeLists.txtnew file+1

This diff is too big to show here.

src/Panel/Indicators/CMakeLists.txtnew file+1

This diff is too big to show here.

tools/indicatorsclient/CMakeLists.txt → src/Panel/Indicators/client/CMakeLists.txtrenamed+7−1

This diff is too big to show here.

tools/indicatorsclient/indicatorsclient.cpp → src/Panel/Indicators/client/indicatorsclient.cpprenamed+50−22

This diff is too big to show here.

tools/indicatorsclient/indicatorsclient.h → src/Panel/Indicators/client/indicatorsclient.hrenamed+2

This diff is too big to show here.

tools/indicatorsclient/main.cpp → src/Panel/Indicators/client/main.cpprenamed

The content is the same.

src/SecondaryWindow.cppdeleted−40

This diff is too big to show here.

src/ShellApplication.cppdeleted−231

This diff is too big to show here.

src/ShellApplication.hdeleted−61

This diff is too big to show here.

src/ShellView.cppdeleted−85

This diff is too big to show here.

src/UnityCommandLineParser.cppdeleted−130

This diff is too big to show here.

src/UnityCommandLineParser.hdeleted−60

This diff is too big to show here.

src/UnixSignalHandler.cppdeleted−139

This diff is too big to show here.

src/UnixSignalHandler.hdeleted−54

This diff is too big to show here.

src/libunity8-private/CMakeLists.txtdeleted−27

This diff is too big to show here.

src/libunity8-private/abstractdbusservicemonitor.cppdeleted−100

This diff is too big to show here.

src/libunity8-private/abstractdbusservicemonitor.hdeleted−70

This diff is too big to show here.

src/libunity8-private/unitydbusobject.cppdeleted−86

This diff is too big to show here.

src/libunity8-private/unitydbusobject.hdeleted−46

This diff is too big to show here.

src/libunity8-private/unitydbusvirtualobject.cppdeleted−83

This diff is too big to show here.

src/libunity8-private/unitydbusvirtualobject.hdeleted−47

This diff is too big to show here.

src/main.cppdeleted−67

This diff is too big to show here.

src/qmldebuggerutils.hdeleted−33

This diff is too big to show here.

tests/CMakeLists.txt+9−148

This diff is too big to show here.

tests/autopilot/setup.py+2−2

This diff is too big to show here.

tests/autopilot/unity8/__init__.py+15−26

This diff is too big to show here.

tests/autopilot/unity8/application_lifecycle/tests/__init__.py−49

This diff is too big to show here.

tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py+84−89

This diff is too big to show here.

tests/autopilot/unity8/application_lifecycle/tests/test_url_dispatcher.pydeleted−51

This diff is too big to show here.

tests/autopilot/unity8/fixture_setup.pydeleted−329

This diff is too big to show here.

tests/autopilot/unity8/greeter/__init__.pydeleted−97

This diff is too big to show here.

tests/autopilot/unity8/greeter/tests/test_args.pydeleted−49

This diff is too big to show here.

tests/autopilot/unity8/indicators/__init__.pydeleted−203

This diff is too big to show here.

tests/autopilot/unity8/indicators/tests/__init__.pydeleted−42

This diff is too big to show here.

tests/autopilot/unity8/indicators/tests/test_action_latency.pydeleted−237

This diff is too big to show here.

tests/autopilot/unity8/indicators/tests/test_display_indicator.pydeleted−52

This diff is too big to show here.

tests/autopilot/unity8/indicators/tests/test_indicators.pydeleted−88

This diff is too big to show here.

tests/autopilot/unity8/launcher.pydeleted−66

This diff is too big to show here.

tests/autopilot/unity8/process_helpers.py+63−138

This diff is too big to show here.

tests/autopilot/unity8/sensors.pydeleted−93

This diff is too big to show here.

tests/autopilot/unity8/shell/__init__.py+27−230

This diff is too big to show here.

tests/autopilot/unity8/greeter/tests/__init__.py → tests/autopilot/unity8/shell/emulators/__init__.pyrenamed+5−8

This diff is too big to show here.

tests/autopilot/unity8/shell/create_interactive_notification.py → tests/autopilot/unity8/shell/emulators/create_interactive_notification.pyrenamed+4−3

This diff is too big to show here.

tests/autopilot/unity8/shell/emulators/dash.pynew file+51

This diff is too big to show here.

tests/autopilot/unity8/shell/emulators/greeter.pynew file+43

This diff is too big to show here.

tests/autopilot/unity8/shell/emulators/hud.pynew file+87

This diff is too big to show here.

tests/autopilot/unity8/shell/emulators.py → tests/autopilot/unity8/shell/emulators/launcher.pyrenamed+15−27

This diff is too big to show here.

tests/autopilot/unity8/shell/emulators/main_window.pynew file+95

This diff is too big to show here.

tests/autopilot/unity8/shell/fixture_setup.pydeleted−65

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/__init__.py+215−183

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/test_helpers.pydeleted−44

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/test_hud.pynew file+190

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/test_lock_screen.py+79−47

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/test_notifications.py+207−187

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/test_rotation.pydeleted−113

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/test_system_integration.pydeleted−48

This diff is too big to show here.

tests/autopilot/unity8/shell/tests/test_upstart.pydeleted−137

This diff is too big to show here.

tests/copyright/CMakeLists.txt+1−1

This diff is too big to show here.

tests/copyright/check_copyright.sh+4−35

This diff is too big to show here.

tests/data/unity/backgrounds/20x30.pngdeleted

Binary file not shown.

tests/data/unity/backgrounds/black.pngdeleted

Binary file not shown.

tests/data/unity/backgrounds/blue.png

Binary file not shown.

tests/data/unity/backgrounds/red.png

Binary file not shown.

tests/data/unity/indicators/com.canonical.indicator.fake1+4−4

This diff is too big to show here.

tests/data/unity/indicators/com.canonical.indicator.fake2+4−4

This diff is too big to show here.

tests/data/unity/indicators/com.canonical.indicator.fake3+4−4

This diff is too big to show here.

tests/data/unity/indicators/com.canonical.indicator.fake4+4−4

This diff is too big to show here.

tests/graphics/applicationIcons/browser@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/calendar@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/camera@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/contacts-app@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/dash@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/dialer-app@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/evernote@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/facebook@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/gallery@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/gmail@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/libreoffice@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/map@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/messages-app@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/notepad@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/pinterest@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/soundcloud@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/system-settings@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/twitter@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/weather@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/wikipedia@18.pngdeleted

Binary file not shown.

tests/graphics/applicationIcons/youtube@18.pngdeleted

Binary file not shown.

tests/graphics/avatars/amanda@12.pngdeleted

Binary file not shown.

tests/graphics/avatars/anna_olsson@12.pngdeleted

Binary file not shown.

tests/graphics/avatars/funky@12.pngdeleted

Binary file not shown.

tests/graphics/clock@18.pngdeleted

Binary file not shown.

tests/imports/CMakeLists.txtdeleted−5

This diff is too big to show here.

tests/imports/check_imports.pydeleted−183

This diff is too big to show here.

tests/mocks/AccountsService/AccountsService.cpp+10−156

This diff is too big to show here.

tests/mocks/AccountsService/AccountsService.h+8−86

This diff is too big to show here.

tests/mocks/AccountsService/CMakeLists.txt+12−15

This diff is too big to show here.

tests/mocks/AccountsService/plugin.cpp+1−2

This diff is too big to show here.

tests/mocks/AccountsService/plugin.h+1−1

This diff is too big to show here.

tests/mocks/AccountsService/qmldir−1

This diff is too big to show here.

tests/mocks/Biometryd/CMakeLists.txtdeleted−14

This diff is too big to show here.

tests/mocks/Biometryd/MockBiometryd.cppdeleted−43

This diff is too big to show here.

tests/mocks/Biometryd/MockBiometryd.hdeleted−50

This diff is too big to show here.

tests/mocks/Biometryd/MockDevice.cppdeleted−29

This diff is too big to show here.

tests/mocks/Biometryd/MockDevice.hdeleted−40

This diff is too big to show here.

tests/mocks/Biometryd/MockIdentifier.hdeleted−36

This diff is too big to show here.

tests/mocks/Biometryd/MockOperation.cppdeleted−56

This diff is too big to show here.

tests/mocks/Biometryd/MockOperation.hdeleted−47

This diff is too big to show here.

tests/mocks/Biometryd/plugin.cppdeleted−41

This diff is too big to show here.

tests/mocks/Biometryd/plugin.hdeleted−31

This diff is too big to show here.

tests/mocks/Biometryd/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/CMakeLists.txt+2−41

This diff is too big to show here.

tests/mocks/Cursor/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Cursor/Cursor.qmldeleted−34

This diff is too big to show here.

tests/mocks/Cursor/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/GSettings.1.0/CMakeLists.txt+6−2

This diff is too big to show here.

tests/mocks/GSettings.1.0/fake_gsettings.cpp+20−335

This diff is too big to show here.

tests/mocks/GSettings.1.0/fake_gsettings.h+13−103

This diff is too big to show here.

tests/mocks/GSettings.1.0/plugin.h+1−1

This diff is too big to show here.

tests/mocks/GSettings.1.0/qmldir−1

This diff is too big to show here.

tests/mocks/HudClient/CMakeLists.txtnew file+41

This diff is too big to show here.

plugins/Lights/HfdLights.h → tests/mocks/HudClient/fake_hud_plugin.cpprenamed+18−21

This diff is too big to show here.

tests/mocks/LightDMController/plugin.h → tests/mocks/HudClient/fake_hud_plugin.hrenamed+8−6

This diff is too big to show here.

tests/mocks/HudClient/fake_libhud_client.cppnew file+240

This diff is too big to show here.

tests/mocks/HudClient/libhud_client_stub.cppnew file+93

This diff is too big to show here.

tests/mocks/HudClient/libhud_client_stub.hnew file+64

This diff is too big to show here.

tests/mocks/HudClient/qmldirnew file+1

This diff is too big to show here.

tests/mocks/LightDM/CMakeLists.txtnew file+55

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/Greeter.cpp → tests/mocks/LightDM/Greeter.cpprenamed+14−29

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/Greeter.h → tests/mocks/LightDM/Greeter.hrenamed+6−9

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/GreeterPrivate.h → tests/mocks/LightDM/GreeterPrivate.hrenamed+2−4

This diff is too big to show here.

tests/mocks/LightDM/QLightDM/Greeternew file+1

This diff is too big to show here.

tests/mocks/LightDM/QLightDM/InfographicModelnew file+1

This diff is too big to show here.

tests/mocks/LightDM/QLightDM/UsersModelnew file+1

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/UsersModel.cpp → tests/mocks/LightDM/UsersModel.cpprenamed+21−14

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/liblightdm/UsersModel.h → tests/mocks/LightDM/UsersModel.hrenamed+6−10

This diff is too big to show here.

tests/mocks/liblightdm/UsersModelPrivate.h → tests/mocks/LightDM/UsersModelPrivate.hrenamed+3−8

This diff is too big to show here.

tests/mocks/liblightdm/demo/CMakeLists.txt → tests/mocks/LightDM/demo/CMakeLists.txtrenamed+2−1

This diff is too big to show here.

tests/mocks/liblightdm/demo/GreeterPrivate.cpp → tests/mocks/LightDM/demo/GreeterPrivate.cpprenamed−2

This diff is too big to show here.

tests/mocks/LightDM/demo/InfographicModelPrivate.cppnew file+91

This diff is too big to show here.

tests/mocks/Biometryd/MockIdentifier.cpp → tests/mocks/LightDM/demo/UsersModelPrivate.cpprenamed+13−8

This diff is too big to show here.

tests/mocks/LightDM/full/CMakeLists.txtnew file+18

This diff is too big to show here.

tests/mocks/liblightdm/GreeterPrivate.cpp → tests/mocks/LightDM/full/GreeterPrivate.cpprenamed+10−44

This diff is too big to show here.

tests/mocks/LightDM/full/InfographicModelPrivate.cppnew file+182

This diff is too big to show here.

tests/mocks/LightDM/full/UsersModelPrivate.cppnew file+52

This diff is too big to show here.

tests/mocks/liblightdm/qmldir → tests/mocks/LightDM/qmldirrenamed−1

This diff is too big to show here.

tests/mocks/LightDM/single-passphrase/CMakeLists.txtnew file+19

This diff is too big to show here.

tests/mocks/LightDM/single-passphrase/GreeterPrivate.cppnew file+53

This diff is too big to show here.

tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cppnew file+61

This diff is too big to show here.

tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cppnew file+33

This diff is too big to show here.

tests/mocks/LightDM/single-pin/CMakeLists.txtnew file+19

This diff is too big to show here.

tests/mocks/LightDM/single-pin/GreeterPrivate.cppnew file+53

This diff is too big to show here.

tests/mocks/LightDM/single-pin/InfographicModelPrivate.cppnew file+61

This diff is too big to show here.

tests/mocks/LightDM/single-pin/UsersModelPrivate.cppnew file+33

This diff is too big to show here.

tests/mocks/LightDM/single/CMakeLists.txtnew file+18

This diff is too big to show here.

tests/mocks/liblightdm/demo/UsersModelPrivate.cpp → tests/mocks/LightDM/single/GreeterPrivate.cpprenamed+19−14

This diff is too big to show here.

tests/mocks/LightDM/single/InfographicModelPrivate.cppnew file+28

This diff is too big to show here.

tests/mocks/LightDM/single/UsersModelPrivate.cppnew file+33

This diff is too big to show here.

tests/mocks/LightDMController/CMakeLists.txtdeleted−14

This diff is too big to show here.

tests/mocks/LightDMController/plugin.cppdeleted−35

This diff is too big to show here.

tests/mocks/LightDMController/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Lights/CMakeLists.txtdeleted−8

This diff is too big to show here.

tests/mocks/Lights/Lights.cppdeleted−84

This diff is too big to show here.

tests/mocks/Lights/Lights.hdeleted−66

This diff is too big to show here.

tests/mocks/Lights/plugin.hdeleted−32

This diff is too big to show here.

tests/mocks/Lights/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/MeeGo/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/CMakeLists.txtdeleted−11

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/MockOfonoSimManager.qmldeleted−53

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/MockQOfono.cppdeleted−90

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/MockQOfono.hdeleted−61

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/MockQOfonoManager.cppdeleted−66

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/MockQOfonoManager.hdeleted−49

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/plugin.cppdeleted−35

This diff is too big to show here.

tests/mocks/MeeGo/QOfono/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/Powerd/CMakeLists.txt+13−2

This diff is too big to show here.

tests/mocks/Powerd/Powerd.cpp+1−15

This diff is too big to show here.

tests/mocks/Powerd/Powerd.h+8−17

This diff is too big to show here.

tests/mocks/Powerd/plugin.h+1−1

This diff is too big to show here.

tests/mocks/Powerd/qmldir−1

This diff is too big to show here.

tests/mocks/QMenuModel/CMakeLists.txt+8−22

This diff is too big to show here.

tests/mocks/QMenuModel/QDBusActionGroup.qml+5−30

This diff is too big to show here.

qml/Panel/FakePanelMenu.qml → tests/mocks/QMenuModel/UnityMenuModel.qmlrenamed+8−8

This diff is too big to show here.

tests/mocks/QMenuModel/plugin.cppdeleted−43

This diff is too big to show here.

tests/mocks/QMenuModel/plugin.hdeleted−34

This diff is too big to show here.

tests/mocks/QMenuModel/qmldir+1−4

This diff is too big to show here.

tests/mocks/QMenuModel/unitymenumodel.cppdeleted−310

This diff is too big to show here.

tests/mocks/QMenuModel/unitymenumodel.hdeleted−115

This diff is too big to show here.

tests/mocks/QtMultimedia/CMakeLists.txtdeleted−15

This diff is too big to show here.

tests/mocks/QtMultimedia/VideoSurface.qmldeleted−111

This diff is too big to show here.

tests/mocks/QtMultimedia/declarativeplaylist.cppdeleted−73

This diff is too big to show here.

tests/mocks/QtMultimedia/declarativeplaylist.hdeleted−54

This diff is too big to show here.

tests/mocks/QtMultimedia/mediaplayer.cppdeleted−319

This diff is too big to show here.

tests/mocks/QtMultimedia/mediaplayer.hdeleted−224

This diff is too big to show here.

tests/mocks/QtMultimedia/plugin.cppdeleted−35

This diff is too big to show here.

tests/mocks/QtMultimedia/plugin.hdeleted−34

This diff is too big to show here.

tests/mocks/QtMultimedia/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/QtMultimedia/videooutput.cppdeleted−127

This diff is too big to show here.

tests/mocks/QtMultimedia/videooutput.hdeleted−52

This diff is too big to show here.

tests/mocks/SessionBroadcast/CMakeLists.txtdeleted−8

This diff is too big to show here.

tests/mocks/SessionBroadcast/SessionBroadcast.cppdeleted−34

This diff is too big to show here.

tests/mocks/SessionBroadcast/plugin.cppdeleted−31

This diff is too big to show here.

tests/mocks/SessionBroadcast/plugin.hdeleted−32

This diff is too big to show here.

tests/mocks/SessionBroadcast/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/UInput/CMakeLists.txtdeleted−7

This diff is too big to show here.

tests/mocks/UInput/mockuinput.cppdeleted−73

This diff is too big to show here.

tests/mocks/UInput/mockuinput.hdeleted−63

This diff is too big to show here.

tests/mocks/UInput/plugin.cppdeleted−26

This diff is too big to show here.

tests/mocks/UInput/plugin.hdeleted−32

This diff is too big to show here.

tests/mocks/UInput/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Ubuntu/CMakeLists.txt−5

This diff is too big to show here.

tests/mocks/Ubuntu/Connectivity/CMakeLists.txtdeleted−10

This diff is too big to show here.

tests/mocks/Ubuntu/Connectivity/networking-status.cppdeleted−70

This diff is too big to show here.

tests/mocks/Ubuntu/Connectivity/networking-status.hdeleted−74

This diff is too big to show here.

tests/mocks/Ubuntu/Connectivity/plugin.cppdeleted−47

This diff is too big to show here.

tests/mocks/Ubuntu/Connectivity/plugin.hdeleted−35

This diff is too big to show here.

tests/mocks/Ubuntu/Connectivity/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt+10−2

This diff is too big to show here.

tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp+1−3

This diff is too big to show here.

tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.h+1−2

This diff is too big to show here.

tests/mocks/Ubuntu/DownloadDaemonListener/plugin.h+1−1

This diff is too big to show here.

tests/mocks/Ubuntu/DownloadDaemonListener/qmldir−1

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/CMakeLists.txtdeleted−5

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/Diagnostics/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/Diagnostics/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockLanguagePlugin.qmldeleted−24

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/CMakeLists.txtdeleted−10

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.hdeleted−50

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/plugin.cppdeleted−26

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/plugin.hdeleted−31

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/TimeDate/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/TimeDate/MockTimeDate.qmldeleted−37

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/TimeDate/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/Update/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/Update/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/CMakeLists.txtdeleted−14

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/ContactWatcherData.cppdeleted−43

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/ContactWatcherData.hdeleted−46

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockCallEntry.cppdeleted−91

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockCallEntry.hdeleted−65

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockCallManager.cppdeleted−80

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockCallManager.hdeleted−60

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockContactWatcher.cppdeleted−50

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockContactWatcher.hdeleted−49

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockTelepathyHelper.cppdeleted−62

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/MockTelepathyHelper.hdeleted−58

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/plugin.cppdeleted−52

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/plugin.hdeleted−37

This diff is too big to show here.

tests/mocks/Ubuntu/Telephony/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Ubuntu/Thumbnailer/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Ubuntu/Thumbnailer/qmldirdeleted−4

This diff is too big to show here.

tests/mocks/Ubuntu/Web/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Ubuntu/Web/qmldirdeleted−4

This diff is too big to show here.

tests/mocks/Unity/Application/ApplicationImage.cppnew file+123

This diff is too big to show here.

tests/mocks/Unity/Application/ApplicationImage.hnew file+79

This diff is too big to show here.

tests/mocks/Unity/Application/ApplicationInfo.cpp+47−362

This diff is too big to show here.

tests/mocks/Unity/Application/ApplicationInfo.h+63−123

This diff is too big to show here.

tests/mocks/Unity/Application/ApplicationManager.cpp+239−323

This diff is too big to show here.

tests/mocks/Unity/Application/ApplicationManager.h+66−55

This diff is too big to show here.

tests/mocks/Unity/Application/CMakeLists.txt+25−23

This diff is too big to show here.

tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockKeyboardPlugin.qml → tests/mocks/Unity/Application/InputFilterArea.qmlrenamed+3−3

This diff is too big to show here.

tests/mocks/Unity/Application/MirMock.cppdeleted−62

This diff is too big to show here.

tests/mocks/Unity/Application/MirSurface.cppdeleted−559

This diff is too big to show here.

tests/mocks/Unity/Application/MirSurface.hdeleted−237

This diff is too big to show here.

tests/mocks/Unity/Application/MirSurfaceItem.cppdeleted−415

This diff is too big to show here.

tests/mocks/Unity/Application/MirSurfaceItem.hdeleted−138

This diff is too big to show here.

tests/mocks/Unity/Application/MirSurfaceListModel.cppdeleted−136

This diff is too big to show here.

tests/mocks/Unity/Application/MirSurfaceListModel.hdeleted−54

This diff is too big to show here.

plugins/Wizard/Unity/Application/OSKController.qml → tests/mocks/Unity/Application/OSKController.qmlrenamed

The content is the same.

tests/mocks/Unity/Application/ObjectListModel.hdeleted−108

This diff is too big to show here.

tests/mocks/Unity/Application/SurfaceManager.cppdeleted−281

This diff is too big to show here.

tests/mocks/Unity/Application/SurfaceManager.hdeleted−116

This diff is too big to show here.

tests/mocks/Unity/Application/VirtualKeyboard.cppdeleted−58

This diff is too big to show here.

tests/mocks/Unity/Application/VirtualKeyboard.hdeleted−37

This diff is too big to show here.

tests/mocks/Unity/Application/plugin.cpp+9−38

This diff is too big to show here.

tests/mocks/Unity/Application/plugin.h+1−2

This diff is too big to show here.

tests/mocks/Unity/Application/qmldir+2−1

This diff is too big to show here.

tests/mocks/Unity/Application/resources/Kate.qmldeleted−49

This diff is too big to show here.

tests/mocks/Unity/Application/resources/KateDialog.qmldeleted−48

This diff is too big to show here.

tests/mocks/Unity/Application/resources/MirSurfaceItem.qmldeleted−126

This diff is too big to show here.

tests/mocks/Unity/Application/resources/VirtualKeyboard.qmldeleted−41

This diff is too big to show here.

tests/mocks/Unity/Application/resources/screenshots/browser@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/camera@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/dialer@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/facebook@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/gallery@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/gmail-webapp.svgdeleted−343

This diff is too big to show here.

tests/mocks/Unity/Application/resources/screenshots/libreoffice@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/map@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/music@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/twitter@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/ubuntu-weather-app.svgdeleted−201

This diff is too big to show here.

tests/mocks/Unity/Application/resources/screenshots/unity8-dash@12.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/screenshots/vkb_portrait.pngdeleted

Binary file not shown.

tests/mocks/Unity/Application/resources/surfaces.qrcdeleted−23

This diff is too big to show here.

tests/mocks/Unity/Application/resources/vkb_portrait.pngdeleted

Binary file not shown.

tests/mocks/Unity/ApplicationMenu/CMakeLists.txtdeleted−18

This diff is too big to show here.

tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.cppdeleted−47

This diff is too big to show here.

tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.hdeleted−41

This diff is too big to show here.

tests/mocks/Unity/ApplicationMenu/plugin.cppdeleted−42

This diff is too big to show here.

tests/mocks/Unity/ApplicationMenu/plugin.hdeleted−32

This diff is too big to show here.

tests/mocks/Unity/ApplicationMenu/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/Unity/CMakeLists.txt+42−5

This diff is too big to show here.

tests/mocks/Unity/Connectivity/CMakeLists.txtdeleted−10

This diff is too big to show here.

tests/mocks/Unity/Connectivity/MockConnectivity.cppdeleted−27

This diff is too big to show here.

tests/mocks/Unity/Connectivity/plugin.cppdeleted−34

This diff is too big to show here.

tests/mocks/Unity/Connectivity/plugin.hdeleted−31

This diff is too big to show here.

tests/mocks/Unity/Connectivity/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/Unity/Indicators/ActionRootState.qmldeleted−46

This diff is too big to show here.

tests/mocks/Unity/Indicators/CMakeLists.txt+24−13

This diff is too big to show here.

plugins/Unity/InputInfo/plugin.h → tests/mocks/Unity/Indicators/CachedUnityMenuModel.qmlrenamed+12−12

This diff is too big to show here.

tests/mocks/Unity/Indicators/IndicatorsModel.qml+41−237

This diff is too big to show here.

tests/mocks/Unity/Indicators/ModelActionRootState.qmldeleted−81

This diff is too big to show here.

tests/mocks/Unity/Indicators/RootActionState.qmlnew file+33

This diff is too big to show here.

tests/mocks/Unity/Indicators/fakeindicatorsmodel.cppdeleted−157

This diff is too big to show here.

tests/mocks/Unity/Indicators/fakeindicatorsmodel.hdeleted−70

This diff is too big to show here.

tests/mocks/Unity/Indicators/fakeindicatorsmodeldata.jsdeleted−1328

This diff is too big to show here.

tests/mocks/Unity/Indicators/fakeplugin.cpp+3−24

This diff is too big to show here.

tests/mocks/Unity/Indicators/fakeplugin.h+1−1

This diff is too big to show here.

tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cppdeleted−59

This diff is too big to show here.

tests/mocks/Unity/Indicators/fakeunitymenumodelcache.hdeleted−45

This diff is too big to show here.

tests/mocks/Unity/Indicators/indicators_fake.qrcnew file+14

This diff is too big to show here.

tests/mocks/Unity/Indicators/qml/FakeMenuPage.qmlnew file+37

This diff is too big to show here.

tests/mocks/Unity/Indicators/qml/fake_menu_page1.qmlnew file+36

This diff is too big to show here.

tests/mocks/Unity/Indicators/qml/fake_menu_page2.qmlnew file+36

This diff is too big to show here.

tests/mocks/Unity/Indicators/qml/fake_menu_page3.qmlnew file+36

This diff is too big to show here.

tests/mocks/Unity/Indicators/qml/fake_menu_page4.qmlnew file+36

This diff is too big to show here.

tests/mocks/Unity/Indicators/qml/fake_menu_page5.qmlnew file+36

This diff is too big to show here.

plugins/Lights/android-hardware.h → tests/mocks/Unity/Indicators/qml/fake_menu_widget1.qmlrenamed+8−4

This diff is too big to show here.

tests/mocks/Biometryd/MockObserver.cpp → tests/mocks/Unity/Indicators/qml/fake_menu_widget2.qmlrenamed+8−5

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/QLightDM/Greeter → tests/mocks/Unity/Indicators/qml/fake_menu_widget3.qmlrenamed+8−2

This diff is too big to show here.

plugins/LightDM/IntegratedLightDM/QLightDM/UsersModel → tests/mocks/Unity/Indicators/qml/fake_menu_widget4.qmlrenamed+8−2

This diff is too big to show here.

tests/mocks/Unity/Indicators/qml/fake_menu_widget5.qmlnew file+23

This diff is too big to show here.

tests/mocks/Unity/Indicators/qmldir+3−3

This diff is too big to show here.

tests/mocks/Unity/InputInfo/CMakeLists.txtdeleted−31

This diff is too big to show here.

tests/mocks/Unity/InputInfo/mockcontroller.cppdeleted−35

This diff is too big to show here.

tests/mocks/Unity/InputInfo/mockcontroller.hdeleted−34

This diff is too big to show here.

tests/mocks/Unity/InputInfo/plugin.cppdeleted−46

This diff is too big to show here.

tests/mocks/Unity/InputInfo/qinputdeviceinfo_mock.cppdeleted−56

This diff is too big to show here.

tests/mocks/Unity/InputInfo/qinputdeviceinfo_mock_p.hdeleted−58

This diff is too big to show here.

tests/mocks/Unity/InputInfo/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Unity/Launcher/CMakeLists.txt+11−7

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockAppDrawerModel.cppdeleted−98

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockAppDrawerModel.hdeleted−43

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockLauncherItem.cpp+1−79

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockLauncherItem.h+17−34

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockLauncherModel.cpp+5−112

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockLauncherModel.h+11−22

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockQuickListModel.cpp+2−6

This diff is too big to show here.

tests/mocks/Unity/Launcher/MockQuickListModel.h+2−4

This diff is too big to show here.

tests/mocks/Unity/Launcher/plugin.cpp−4

This diff is too big to show here.

tests/mocks/Unity/Launcher/plugin.h+1−1

This diff is too big to show here.

tests/mocks/Unity/Launcher/qmldir−1

This diff is too big to show here.

tests/mocks/Unity/Notifications/CMakeLists.txt+8−13

This diff is too big to show here.

tests/mocks/Unity/Notifications/MockActionModel.cppdeleted−74

This diff is too big to show here.

tests/mocks/Unity/Notifications/MockActionModel.hdeleted−53

This diff is too big to show here.

tests/mocks/Unity/Notifications/MockNotification.cppdeleted−198

This diff is too big to show here.

tests/mocks/Unity/Notifications/MockNotification.hdeleted−101

This diff is too big to show here.

tests/mocks/Unity/Notifications/MockNotificationModel.cppdeleted−169

This diff is too big to show here.

tests/mocks/Unity/Notifications/MockNotificationModel.hdeleted−70

This diff is too big to show here.

src/ApplicationArguments.cpp → tests/mocks/Unity/Notifications/notification.jsrenamed+7−6

This diff is too big to show here.

tests/mocks/Unity/Notifications/qmldir+1−3

This diff is too big to show here.

tests/mocks/Unity/Platform/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/mocks/Unity/Platform/MockPlatform.qmldeleted−25

This diff is too big to show here.

tests/mocks/Unity/Platform/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Unity/Screens/CMakeLists.txtdeleted−14

This diff is too big to show here.

tests/mocks/Unity/Screens/plugin.cppdeleted−29

This diff is too big to show here.

tests/mocks/Unity/Screens/plugin.hdeleted−25

This diff is too big to show here.

tests/mocks/Unity/Screens/qmldirdeleted−2

This diff is too big to show here.

tests/mocks/Unity/Screens/screens.cppdeleted−71

This diff is too big to show here.

tests/mocks/Unity/Screens/screens.hdeleted−82

This diff is too big to show here.

tests/mocks/Unity/fake_applications_scope.cppnew file+75

This diff is too big to show here.

plugins/Unity/Platform/plugin.h → tests/mocks/Unity/fake_applications_scope.hrenamed+10−9

This diff is too big to show here.

tests/mocks/Unity/fake_categories.cppnew file+259

This diff is too big to show here.

tests/mocks/Unity/fake_categories.hnew file+75

This diff is too big to show here.

tests/mocks/Unity/fake_preview.cppnew file+71

This diff is too big to show here.

tests/mocks/Unity/fake_preview.hnew file+62

This diff is too big to show here.

tests/mocks/Unity/fake_scope.cppnew file+271

This diff is too big to show here.

tests/mocks/Unity/fake_scope.hnew file+125

This diff is too big to show here.

tests/mocks/Unity/fake_scopes.cppnew file+149

This diff is too big to show here.

tests/mocks/Unity/fake_scopes.hnew file+79

This diff is too big to show here.

tests/mocks/Unity/fake_unity_plugin.cppnew file+47

This diff is too big to show here.

plugins/UInput/plugin.h → tests/mocks/Unity/fake_unity_plugin.hrenamed+8−6

This diff is too big to show here.

tests/mocks/Unity/qmldirnew file+2

This diff is too big to show here.

tests/mocks/Utils/CMakeLists.txtdeleted−61

This diff is too big to show here.

tests/mocks/Utils/Style.jsdeleted−37

This diff is too big to show here.

tests/mocks/Utils/URLDispatcher.hdeleted−47

This diff is too big to show here.

tests/mocks/Utils/WindowInputMonitor.qmldeleted−23

This diff is too big to show here.

tests/mocks/Utils/constants.cppdeleted−24

This diff is too big to show here.

tests/mocks/Utils/constants.hdeleted−43

This diff is too big to show here.

tests/mocks/Utils/plugin.cppdeleted−93

This diff is too big to show here.

tests/mocks/Utils/plugin.hdeleted−32

This diff is too big to show here.

tests/mocks/Utils/qmldirdeleted−6

This diff is too big to show here.

tests/mocks/Utils/windowstatestorage.cppdeleted−100

This diff is too big to show here.

tests/mocks/Utils/windowstatestorage.hdeleted−77

This diff is too big to show here.

tests/mocks/Wizard/CMakeLists.txtdeleted−20

This diff is too big to show here.

tests/mocks/Wizard/MockSystem.cppdeleted−64

This diff is too big to show here.

tests/mocks/Wizard/MockSystem.hdeleted−61

This diff is too big to show here.

tests/mocks/Wizard/mockplugin.cppdeleted−38

This diff is too big to show here.

tests/mocks/Wizard/mockplugin.hdeleted−32

This diff is too big to show here.

tests/mocks/Wizard/qmldirdeleted−3

This diff is too big to show here.

tests/mocks/data/applications/webbrowser-app.desktop → tests/mocks/data/applications/camera-app.desktoprenamed

The content is the same.

tests/mocks/data/unity/indicators/com.canonical.indicator.mockdeleted−10

This diff is too big to show here.

tests/mocks/indicator-service/CMakeLists.txtdeleted−19

This diff is too big to show here.

tests/mocks/indicator-service/mock-indicator-service.cdeleted−325

This diff is too big to show here.

tests/mocks/liblightdm/CMakeLists.txtdeleted−18

This diff is too big to show here.

tests/mocks/liblightdm/GreeterPrivate.hdeleted−54

This diff is too big to show here.

tests/mocks/liblightdm/MockController.cppdeleted−192

This diff is too big to show here.

tests/mocks/liblightdm/MockController.hdeleted−106

This diff is too big to show here.

tests/mocks/liblightdm/MockGreeter.cppdeleted−316

This diff is too big to show here.

tests/mocks/liblightdm/MockGreeter.hdeleted−102

This diff is too big to show here.

tests/mocks/liblightdm/MockSessionsModel.cppdeleted−118

This diff is too big to show here.

tests/mocks/liblightdm/MockSessionsModel.hdeleted−64

This diff is too big to show here.

tests/mocks/liblightdm/MockUsersModel.cppdeleted−220

This diff is too big to show here.

tests/mocks/liblightdm/MockUsersModel.hdeleted−61

This diff is too big to show here.

tests/mocks/liblightdm/SessionsModelPrivate.cppdeleted−83

This diff is too big to show here.

tests/mocks/liblightdm/SessionsModelPrivate.hdeleted−63

This diff is too big to show here.

tests/mocks/liblightdm/UsersModelPrivate.cppdeleted−124

This diff is too big to show here.

tests/mocks/libusermetrics/CMakeLists.txt+2−7

This diff is too big to show here.

tests/mocks/libusermetrics/ColorTheme.cpp−4

This diff is too big to show here.

tests/mocks/libusermetrics/ColorTheme.h+1−2

This diff is too big to show here.

tests/mocks/libusermetrics/UserMetrics.cpp+26−56

This diff is too big to show here.

tests/mocks/libusermetrics/UserMetrics.h−2

This diff is too big to show here.

tests/mocks/libusermetrics/libusermetricsoutput/ColorTheme.hnew file+1

This diff is too big to show here.

tests/mocks/libusermetrics/libusermetricsoutput/UserMetrics.hnew file+1

This diff is too big to show here.

tests/plugins/AccountsService/AccountsServer.cpp+6−28

This diff is too big to show here.

tests/plugins/AccountsService/AccountsServer.h−5

This diff is too big to show here.

tests/plugins/AccountsService/CMakeLists.txt+7−33

This diff is too big to show here.

tests/plugins/AccountsService/PropertiesServer.cpp+7−104

This diff is too big to show here.

tests/plugins/AccountsService/PropertiesServer.h+3−17

This diff is too big to show here.

tests/plugins/AccountsService/UscServer.cppdeleted−28

This diff is too big to show here.

tests/plugins/AccountsService/UscServer.hdeleted−39

This diff is too big to show here.

tests/plugins/AccountsService/client.cpp+9−303

This diff is too big to show here.

tests/plugins/AccountsService/interfaces.xml−50

This diff is too big to show here.

tests/plugins/AccountsService/server.cpp+6−17

This diff is too big to show here.

tests/plugins/AccountsService/types.hdeleted−25

This diff is too big to show here.

tests/plugins/CMakeLists.txt+1−7

This diff is too big to show here.

tests/plugins/Cursor/CMakeLists.txtdeleted−8

This diff is too big to show here.

tests/plugins/Cursor/TextEntry.qmldeleted−34

This diff is too big to show here.

tests/plugins/Cursor/tst_Cursor.qmldeleted−151

This diff is too big to show here.

tests/plugins/GlobalShortcut/CMakeLists.txtdeleted−19

This diff is too big to show here.

tests/plugins/GlobalShortcut/GlobalShortcutTest.cppdeleted−78

This diff is too big to show here.

tests/plugins/GlobalShortcut/shortcut.qmldeleted−39

This diff is too big to show here.

tests/plugins/Greeter/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/plugins/Greeter/Unity/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/plugins/Greeter/Unity/Launcher/CMakeLists.txtdeleted−42

This diff is too big to show here.

tests/plugins/Greeter/Unity/Launcher/launchermodelastest.cppdeleted−240

This diff is too big to show here.

tests/plugins/LightDM/CMakeLists.txtdeleted−1

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/CMakeLists.txtdeleted−157

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/dbus.cppdeleted−223

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/greeter.qmldeleted−22

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/integrated.cppdeleted−88

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/pam.cppdeleted−54

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/promptsmodel.cppdeleted−175

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/sessionsmodel.cppdeleted−134

This diff is too big to show here.

tests/plugins/LightDM/IntegratedLightDM/usersmodel.cppdeleted−168

This diff is too big to show here.

tests/plugins/ListViewWithPageHeader/CMakeLists.txtnew file+42

This diff is too big to show here.

tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cppnew file+1840

This diff is too big to show here.

tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cppnew file+2092

This diff is too big to show here.

tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsectionexternalmodel.cppnew file+251

This diff is too big to show here.

tests/plugins/ListViewWithPageHeader/test.qmlnew file+96

This diff is too big to show here.

tests/plugins/ListViewWithPageHeader/test_section.qmlnew file+106

This diff is too big to show here.

tests/plugins/ListViewWithPageHeader/test_sectionexternalmodel.qmlnew file+74

This diff is too big to show here.

tests/plugins/SessionBroadcast/BroadcastServer.cppdeleted−33

This diff is too big to show here.

tests/plugins/SessionBroadcast/BroadcastServer.hdeleted−40

This diff is too big to show here.

tests/plugins/SessionBroadcast/CMakeLists.txtdeleted−51

This diff is too big to show here.

tests/plugins/SessionBroadcast/interfaces.xmldeleted−18

This diff is too big to show here.

tests/plugins/SessionBroadcast/server.cppdeleted−37

This diff is too big to show here.

tests/plugins/SessionBroadcast/sessionbroadcasttest.cppdeleted−111

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/CMakeLists.txt+37−52

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/DownwardsLauncher.qmlnew file+87

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/GestureTest.cppdeleted−193

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/GestureTest.hdeleted−102

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/LeftwardsLauncher.qmlnew file+90

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/RightwardsLauncher.qmlnew file+87

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/TestItem.cppdeleted−30

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/TestItem.hdeleted−33

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/UpwardsLauncher.qmlnew file+90

This diff is too big to show here.

tests/mocks/Unity/Application/resources/KateMenu.qml → tests/plugins/Ubuntu/Gestures/edgeDragExample.qmlrenamed+16−17

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_AxisVelocityCalculator.cpp+5−5

This diff is too big to show here.

src/ShellView.h → tests/plugins/Ubuntu/Gestures/tst_Damper.cpprenamed+18−12

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cppnew file+551

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.cppdeleted−131

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.qmldeleted−81

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.cppdeleted−150

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.qmldeleted−62

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_TouchDispatcher.cppdeleted−148

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_TouchGate.cppdeleted−392

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_TouchGestureArea.cppdeleted−300

This diff is too big to show here.

tests/plugins/Ubuntu/Gestures/tst_TouchGestureArea.qmldeleted−90

This diff is too big to show here.

tests/plugins/Unity/CMakeLists.txt+51−2

This diff is too big to show here.

tests/plugins/Unity/Indicators/CMakeLists.txt+28−40

This diff is too big to show here.

tests/plugins/Unity/Indicators/IndicatorsModelTest.cpp−141

This diff is too big to show here.

tests/plugins/Unity/Indicators/RootActionStateTest.cpp−95

This diff is too big to show here.

tests/plugins/Unity/Indicators/SharedUnityMenuModelTest.cpp−102

This diff is too big to show here.

tests/plugins/Unity/Indicators/UnityMenuModelStackTest.cpp−201

This diff is too big to show here.

tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp+9−54

This diff is too big to show here.

tests/plugins/Unity/Indicators/indicatorsmodeltest.cpp+94

This diff is too big to show here.

tests/plugins/Unity/Indicators/menucontentactivatortest.cpp+4−4

This diff is too big to show here.

tests/plugins/Unity/Indicators/rootactionstatetest.cpp+58

This diff is too big to show here.

tests/plugins/Unity/Indicators/timeformattertest.cpp+55

This diff is too big to show here.

tests/plugins/Unity/Launcher/CMakeLists.txt+44−78

This diff is too big to show here.

tests/plugins/Unity/Launcher/abs-icon.desktop−1

This diff is too big to show here.

tests/plugins/Unity/Launcher/appdrawermodeltest.cpp−68

This diff is too big to show here.

tests/plugins/Unity/Launcher/click-icon.desktop−1

This diff is too big to show here.

tests/plugins/Unity/Launcher/click-icon.svg

This diff is too big to show here.

tests/plugins/Unity/Launcher/gsettings.cpp−45

This diff is too big to show here.

tests/plugins/Unity/Launcher/gsettings.h−47

This diff is too big to show here.

tests/plugins/Unity/Launcher/launcherbackendtest.cpp+72

This diff is too big to show here.

tests/plugins/Unity/Launcher/launchermodeltest.cpp+29−590

This diff is too big to show here.

tests/plugins/Unity/Launcher/no-icon.desktop+2

This diff is too big to show here.

tests/plugins/Unity/Launcher/no-name.desktop−1

This diff is too big to show here.

tests/plugins/Unity/Launcher/rel-icon.desktop−1

This diff is too big to show here.

tests/plugins/Unity/Launcher/rel-icon.svg

This diff is too big to show here.

tests/plugins/Unity/Launcher/ualwrapper.cpp−58

This diff is too big to show here.

tests/plugins/Unity/Launcher/ualwrapper.h−55

This diff is too big to show here.

tests/plugins/Unity/Launcher/xdgwatcher.cpp−45

This diff is too big to show here.

tests/plugins/Unity/Launcher/xdgwatcher.h−39

This diff is too big to show here.

tests/plugins/Unity/Platform/CMakeLists.txt−30

This diff is too big to show here.

tests/plugins/Unity/Platform/platformtest.cpp−142

This diff is too big to show here.

tests/plugins/Unity/Session/CMakeLists.txt−72

This diff is too big to show here.

tests/plugins/Unity/Session/LightDMServer.cpp−29

This diff is too big to show here.

tests/plugins/Unity/Session/LightDMServer.h−38

This diff is too big to show here.

tests/plugins/Unity/Session/LogindServer.cpp−43

This diff is too big to show here.

tests/plugins/Unity/Session/LogindServer.h−48

This diff is too big to show here.

tests/plugins/Unity/Session/interfaces.xml−29

This diff is too big to show here.

tests/plugins/Unity/Session/preload.c−43

This diff is too big to show here.

tests/plugins/Unity/Session/server.cpp−50

This diff is too big to show here.

tests/plugins/Unity/Session/sessionbackendtest.cpp−289

This diff is too big to show here.

tests/plugins/Unity/filtersbindingstest.cpp+515

This diff is too big to show here.

tests/plugins/Unity/filtersbindingstest.h+47

This diff is too big to show here.

tests/plugins/Unity/previewbindingstest.cpp+194

This diff is too big to show here.

tests/plugins/Unity/previewbindingstest.h+12−13

This diff is too big to show here.

tests/plugins/Unity/resultstest.cpp+248

This diff is too big to show here.

tests/plugins/Unity/resultstest.h+15−11

This diff is too big to show here.

tests/plugins/Unity/signalslisttest.cpp+57

This diff is too big to show here.

tests/plugins/Unity/signalslisttest.h+8−8

This diff is too big to show here.

tests/plugins/Utils/CMakeLists.txt+19−34

This diff is too big to show here.

tests/plugins/Utils/DeviceConfigParserTest.cpp−76

This diff is too big to show here.

tests/plugins/Utils/URLDispatcherTest.cpp−78

This diff is too big to show here.

tests/plugins/Utils/WindowInputMonitorTest.cpp−461

This diff is too big to show here.

tests/plugins/Utils/WindowStateStorageTest.cpp−121

This diff is too big to show here.

tests/plugins/Utils/modeltest.cpp+42−25

This diff is too big to show here.

tests/plugins/Utils/modeltest.h

This diff is too big to show here.

tests/plugins/Utils/qlimitproxymodeltest.cpp+31−31

This diff is too big to show here.

tests/plugins/Utils/qsortfilterproxymodeltest.cpp+25−25

This diff is too big to show here.

tests/plugins/Utils/tst_UtilsStyle.qml−47

This diff is too big to show here.

tests/plugins/WindowManager/CMakeLists.txt−36

This diff is too big to show here.

tests/plugins/WindowManager/UnityApplicationMocks.h−211

This diff is too big to show here.

tests/plugins/WindowManager/tst_TopLevelWindowModel.cpp−193

This diff is too big to show here.

tests/plugins/Wizard/CMakeLists.txt−24

This diff is too big to show here.

tests/plugins/Wizard/tst_pagelist.cpp−183

This diff is too big to show here.

tests/plugins/Wizard/tst_system.cpp−124

This diff is too big to show here.

tests/qmltests/ApplicationMenuDataLoader.qml−99

This diff is too big to show here.

tests/qmltests/ApplicationMenus/tst_MenuBar.qml−437

This diff is too big to show here.

tests/qmltests/ApplicationMenus/tst_MenuPopup.qml−361

This diff is too big to show here.

tests/qmltests/CMakeLists.txt+72−71

This diff is too big to show here.

tests/qmltests/Components/CMakeLists.txt+13−41

This diff is too big to show here.

tests/qmltests/Components/RevealingRectangle.qml+78

This diff is too big to show here.

tests/qmltests/Components/tst_AnimationControllerWithSignals.qml+142

This diff is too big to show here.

tests/qmltests/Components/tst_Background.qml−91

This diff is too big to show here.

tests/qmltests/Components/tst_Carousel.qml+194

This diff is too big to show here.

tests/qmltests/Components/tst_Dialogs.qml−112

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle.cpp+66−175

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle.qml+57−133

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle/BidirectionalShowable.qml−69

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle/BottomEdgeShowable.qml−108

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle/HorizontalShowable.qml+8−8

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle/RightEdgeShowable.qml−108

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle/TestButton.qml+41

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle/UnityLogo.png

This diff is too big to show here.

tests/qmltests/Components/tst_DragHandle/VerticalShowable.qml+15−15

This diff is too big to show here.

tests/qmltests/Components/tst_DraggingArea.qml+8−8

This diff is too big to show here.

tests/qmltests/Components/tst_EdgeDemoOverlay.qml+123

This diff is too big to show here.

tests/qmltests/Components/tst_EdgeDragEvaluator.cpp−166

This diff is too big to show here.

tests/qmltests/Components/tst_FilterGrid.qml+151

This diff is too big to show here.

tests/qmltests/Components/tst_LazyImage.qml+14−39

This diff is too big to show here.

tests/qmltests/Components/tst_LazyImage/ImageControls.qml+3−3

This diff is too big to show here.

tests/qmltests/Components/tst_LazyImage/portrait.png

This diff is too big to show here.

tests/qmltests/Components/tst_LazyImage/square.png

This diff is too big to show here.

tests/qmltests/Components/tst_LazyImage/wide.png

This diff is too big to show here.

tests/qmltests/Components/tst_Lockscreen.qml−474

This diff is too big to show here.

tests/qmltests/Components/tst_MathLocal.qml+91

This diff is too big to show here.

tests/qmltests/Components/tst_MediaServices.qml−231

This diff is too big to show here.

tests/qmltests/Components/tst_ModeSwitchWarningDialog.qml−75

This diff is too big to show here.

tests/qmltests/Components/tst_OpenEffect.qml+71

This diff is too big to show here.

tests/qmltests/Components/tst_PageHeader.qml+214

This diff is too big to show here.

tests/qmltests/Components/tst_PhysicalKeysMapper.qml−174

This diff is too big to show here.

tests/qmltests/Components/tst_Rating.qml−86

This diff is too big to show here.

tests/qmltests/Components/tst_RatingStars.qml+62

This diff is too big to show here.

tests/qmltests/Components/tst_ResponsiveFlowView.qml+192

This diff is too big to show here.

tests/qmltests/Components/tst_ResponsiveGridView.qml+193

This diff is too big to show here.

tests/qmltests/Components/tst_Revealer.qml+262

This diff is too big to show here.

tests/qmltests/Components/tst_SharingPicker.qml−73

This diff is too big to show here.

tests/qmltests/Components/tst_Showable.qml+3−16

This diff is too big to show here.

tests/qmltests/Components/tst_Stage.qml+278

This diff is too big to show here.

tests/qmltests/Components/tst_Stage/AppControl.qml+17−23

This diff is too big to show here.

tests/qmltests/Components/tst_Stage/FakeApplicationScreenshot.qml+53

This diff is too big to show here.

tests/qmltests/Components/tst_Tile.qml+71

This diff is too big to show here.

tests/qmltests/Components/tst_TimeLocal.qml+117

This diff is too big to show here.

tests/qmltests/Components/tst_VirtualTouchPad.qml−197

This diff is too big to show here.

tests/qmltests/Components/tst_Wallpaper.qml−118

This diff is too big to show here.

tests/qmltests/Components/tst_WallpaperResolver.qml−161

This diff is too big to show here.

tests/qmltests/Components/tst_ZoomableImage.qml−204

This diff is too big to show here.

tests/qmltests/Dash/Apps/tst_AppPreview.qml+276

This diff is too big to show here.

tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+243

This diff is too big to show here.

tests/qmltests/Dash/Movie/tst_MoviePreview.qml+86

This diff is too big to show here.

tests/qmltests/Dash/qml/FakeScopeView.qml+114

This diff is too big to show here.

tests/qmltests/Dash/qml/fake_generic_scopeView.qml+6−7

This diff is too big to show here.

tests/qmltests/Dash/qml/fake_scopeView1.qml+24

This diff is too big to show here.

tests/qmltests/Dash/qml/fake_scopeView2.qml+24

This diff is too big to show here.

tests/qmltests/Dash/qml/fake_scopeView3.qml+24

This diff is too big to show here.

tests/qmltests/Dash/qml/fake_scopeView4.qml+24

This diff is too big to show here.

tests/qmltests/Dash/tst_Dash.qml+133

This diff is too big to show here.

tests/qmltests/Dash/tst_DashBar.qml+111

This diff is too big to show here.

tests/qmltests/Dash/tst_DashContent.qml+233

This diff is too big to show here.

tests/qmltests/Dash/tst_DashPreview.qml+202

This diff is too big to show here.

tests/qmltests/Dash/tst_FilterGrids.qml+144

This diff is too big to show here.

tests/qmltests/Dash/tst_GenericPreview.qml+117

This diff is too big to show here.

tests/qmltests/Dash/tst_GenericScopeView.qml+192

This diff is too big to show here.

tests/qmltests/Dash/tst_ScopeView.qml+52

This diff is too big to show here.

tests/qmltests/EdgeBarrierControls.qml−97

This diff is too big to show here.

tests/qmltests/Greeter/TestView.qml−101

This diff is too big to show here.

tests/qmltests/Greeter/tst_Clock.qml+27−58

This diff is too big to show here.

tests/qmltests/Greeter/tst_Greeter.qml−683

This diff is too big to show here.

tests/qmltests/Greeter/tst_GreeterView.qml−1366

This diff is too big to show here.

tests/qmltests/Greeter/tst_Infographics.qml+17−82

This diff is too big to show here.

tests/qmltests/Greeter/tst_Lockscreen.qml+212

This diff is too big to show here.

tests/qmltests/Greeter/tst_Phone.qml+152

This diff is too big to show here.

tests/qmltests/Greeter/tst_Tablet.qml+328

This diff is too big to show here.

tests/qmltests/Hud/tst_Hud.qml+239

This diff is too big to show here.

tests/qmltests/Hud/tst_Result.qml+98

This diff is too big to show here.

tests/qmltests/Launcher/tst_Drawer.qml−520

This diff is too big to show here.

tests/qmltests/Launcher/tst_Launcher.qml+153−1338

This diff is too big to show here.

tests/qmltests/Notifications/tst_Notifications.qml+331−796

This diff is too big to show here.

tests/qmltests/Notifications/tst_OptionToggle.qml−290

This diff is too big to show here.

tests/qmltests/Notifications/tst_SwipeToAct.qml−326

This diff is too big to show here.

tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml−232

This diff is too big to show here.

tests/qmltests/Panel/Indicators/tst_IndicatorItem.qml−205

This diff is too big to show here.

tests/qmltests/Panel/Indicators/tst_IndicatorMenuItemFactory.qml−828

This diff is too big to show here.

tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml−292

This diff is too big to show here.

tests/qmltests/Panel/Indicators/tst_MessageMenuItemFactory.qml−171

This diff is too big to show here.

tests/qmltests/Panel/PanelTest.qml−70

This diff is too big to show here.

tests/qmltests/Panel/PanelUI.qml−286

This diff is too big to show here.

tests/qmltests/Panel/tst_ActiveCallHint.qml−198

This diff is too big to show here.

tests/qmltests/Panel/tst_IndicatorItem.qml+61

This diff is too big to show here.

tests/qmltests/Panel/tst_IndicatorRow.qml+244

This diff is too big to show here.

tests/qmltests/Panel/tst_Indicators.qml+181

This diff is too big to show here.

tests/qmltests/Panel/tst_MenuContent.qml+91−37

This diff is too big to show here.

tests/qmltests/Panel/tst_Panel.qml+161−600

This diff is too big to show here.

tests/qmltests/Panel/tst_PanelBar.qml−240

This diff is too big to show here.

tests/qmltests/Panel/tst_PanelItemRow.qml−318

This diff is too big to show here.

tests/qmltests/Panel/tst_PanelMenu.qml−364

This diff is too big to show here.

tests/qmltests/Panel/tst_PanelMenuPage.qml−200

This diff is too big to show here.

tests/qmltests/Panel/tst_PanelSmallScreen.qml−133

This diff is too big to show here.

tests/qmltests/Panel/tst_SearchIndicator.qml+62

This diff is too big to show here.

tests/qmltests/SideStage/tst_SideStage.qml+52

This diff is too big to show here.

tests/qmltests/Stage/ApplicationCheckBox.qml−189

This diff is too big to show here.

tests/qmltests/Stage/SizeHintField.qml−33

This diff is too big to show here.

tests/qmltests/Stage/SurfaceManagerControls.qml−32

This diff is too big to show here.

tests/qmltests/Stage/SurfaceManagerField.qml−40

This diff is too big to show here.

tests/qmltests/Stage/tst_ApplicationWindow.qml−513

This diff is too big to show here.

tests/qmltests/Stage/tst_DecoratedWindow.qml−267

This diff is too big to show here.

tests/qmltests/Stage/tst_DesktopStage.qml−1085

This diff is too big to show here.

tests/qmltests/Stage/tst_PhoneStage.qml−624

This diff is too big to show here.

tests/qmltests/Stage/tst_QMLTopLevelWindowModel.qml−191

This diff is too big to show here.

tests/qmltests/Stage/tst_Splash.qml−131

This diff is too big to show here.

tests/qmltests/Stage/tst_SurfaceContainer.qml−258

This diff is too big to show here.

tests/qmltests/Stage/tst_TabletStage.qml−764

This diff is too big to show here.

tests/qmltests/Stage/tst_WindowDecoration.qml−244

This diff is too big to show here.

tests/qmltests/Stage/tst_WindowResizeArea.qml−465

This diff is too big to show here.

tests/qmltests/Tutorial/tst_Tutorial.qml−813

This diff is too big to show here.

tests/qmltests/UnityLogo.png

This diff is too big to show here.

tests/qmltests/Wizard/licenses/en_US.html−1

This diff is too big to show here.

tests/qmltests/Wizard/licenses/fr_CA.html−1

This diff is too big to show here.

tests/qmltests/Wizard/licenses/fr_FR.html−1

This diff is too big to show here.

tests/qmltests/Wizard/tst_Wizard.qml−487

This diff is too big to show here.

tests/qmltests/tst_DeviceConfiguration.qml−49

This diff is too big to show here.

tests/qmltests/tst_DisabledScreenNotice.qml−133

This diff is too big to show here.

tests/qmltests/tst_OrientedShell.qml−1705

This diff is too big to show here.

tests/qmltests/tst_Shell.qml+339−3206

This diff is too big to show here.

tests/qmltests/tst_ShellWithPin.qml−549

This diff is too big to show here.

tests/qmltests/utils/Unity/Test/MockObjectForInstanceOfTest.qml+1−1

This diff is too big to show here.

tests/qmltests/utils/Unity/Test/MockObjectForInstanceOfTestChild.qml+1−1

This diff is too big to show here.

tests/qmltests/utils/Unity/Test/tst_UnityTest.qml+8−36

This diff is too big to show here.

tests/scripts/README−9

This diff is too big to show here.

tests/scripts/alert-launcher-icon.sh−19

This diff is too big to show here.

tests/scripts/get-progress.sh−19

This diff is too big to show here.

tests/scripts/list-launcher-icons.sh−19

This diff is too big to show here.

tests/scripts/set-count-visible.sh−19

This diff is too big to show here.

tests/scripts/set-count.sh−19

This diff is too big to show here.

tests/scripts/set-progress.sh−19

This diff is too big to show here.

tests/uqmlscene/CMakeLists.txt+2−21

This diff is too big to show here.

tests/uqmlscene/README+1−3

This diff is too big to show here.

tests/uqmlscene/main.cpp+12−39

This diff is too big to show here.

tests/utils/modules/Unity/Test/CMakeLists.txt+7−27

This diff is too big to show here.

tests/utils/modules/Unity/Test/StageTestCase.qml−64

This diff is too big to show here.

tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp+2−23

This diff is too big to show here.

tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.h+2−7

This diff is too big to show here.

tests/utils/modules/Unity/Test/UnityTestCase.qml+119−464

This diff is too big to show here.

tests/utils/modules/Unity/Test/plugin.cpp+2−25

This diff is too big to show here.

tests/utils/modules/Unity/Test/plugin.h+1−1

This diff is too big to show here.

tests/utils/modules/Unity/Test/qmldir−4

This diff is too big to show here.

tests/utils/modules/Unity/Test/testutil.cpp+6−49

This diff is too big to show here.

tests/utils/modules/Unity/Test/testutil.h+2−4

This diff is too big to show here.

tests/whitespace/CMakeLists.txt+1−1

This diff is too big to show here.

tests/whitespace/check_whitespace.py+12−22

This diff is too big to show here.

tools/CMakeLists.txt−4

This diff is too big to show here.

tools/menutool/CMakeLists.txt−5

This diff is too big to show here.

tools/menutool/README−11

This diff is too big to show here.

tools/menutool/menutool.cpp−62

This diff is too big to show here.

tools/menutool/menutool.qml−118

This diff is too big to show here.

tools/unlock-device−51

This diff is too big to show here.

unity8.desktop.in+2−1

This diff is too big to show here.

unity8.qmlproject+25

This diff is too big to show here.