on xenial help sign in
make it a listview, update to latest api
commit7f5356b6ec383aae4c6d7e993b1a5ca2eec6b6a1 authorMichael Zanetti <michael.zanetti@canonical.com> dateFri 3 Feb 2017, 17:57 (10 years ago) parentbeafaa2a70a372
9 files changed+223−136
qml/Stage/Spread/ScreensAndWorkspaces.qml+10−15 qml/Stage/Spread/WorkspacePreview.qml+78−54 qml/Stage/Spread/Workspaces.qml+11−7 qml/Stage/Stage.qml+1−1 tests/mocks/Unity/Screens/plugin.cpp+2 tests/mocks/Unity/Screens/screens.cpp+39−42 tests/mocks/Unity/Screens/screens.h+65−9 tests/mocks/Unity/Screens/screenwindow.cpp+7−4 tests/mocks/Unity/Screens/screenwindow.h+10−4
qml/Stage/Spread/ScreensAndWorkspaces.qml+10−15
@@ -20,34 +20,31 @@ Item {
2020
2121 delegate: Item {
2222 height: root.height - units.gu(6)
23− width: workspaces.implicitWidth
23+ width: workspaces.width
2424
25−
26− Rectangle { anchors.fill: parent; color: "blue" }
27−
28− Rectangle {
25+ UbuntuShape {
2926 id: header
3027 anchors { left: parent.left; top: parent.top; right: parent.right }
3128 height: units.gu(7)
32− color: "white"
29+ backgroundColor: "white"
3330
3431 Column {
3532 anchors.fill: parent
3633 anchors.margins: units.gu(1)
3734
3835 Label {
39− text: model.name
36+ text: model.screen.name
4037 color: "black"
4138 }
4239
4340 Label {
44− text: model.outputType === Screens.LVDS ? "Built-in" : "Clone"
41+ text: model.screen.outputType === Screens.LVDS ? "Built-in" : "Clone"
4542 color: "black"
4643 fontSize: "x-small"
4744 }
4845
4946 Label {
50− text: model.geometry.width + "x" + model.geometry.height
47+ text: model.screen.physicalSize.width + "x" + model.screen.physicalSize.height
5148 color: "black"
5249 fontSize: "x-small"
5350 }
@@ -57,14 +54,12 @@ Item {
5754
5855 Workspaces {
5956 id: workspaces
60− height: parent.height - header.height
57+ height: parent.height - header.height - units.gu(2)
58+ width: Math.min(implicitWidth, units.gu(80), root.width)
6159 anchors.bottom: parent.bottom
60+ screen: model.screen
61+ background: root.background
6262 }
63−
64−// WorkspacePreview {
65−// height: root.height - units.gu(6)
66−// background: root.background
67−// }
6863 }
6964 }
7065 }
qml/Stage/Spread/WorkspacePreview.qml+78−54
@@ -2,38 +2,62 @@ import QtQuick 2.4
22import Ubuntu.Components 1.3
33import Unity.Screens 0.1
44import Unity.Application 0.1
5+import ".."
56import "../../Components"
67
7−UbuntuShape {
8+Item {
89 id: previewSpace
910
10− // Set the height. this preview will then automatically adjust the width, keeping aspect ratio of the screen
11− width: model.geometry.width * previewScale * 4
12− color: "white"
1311 property string background
12+ property int screenHeight
1413
15− property int screenWidth: model.geometry.width
16− property int screenHeight: model.geometry.height
1714 property real previewScale: previewSpace.height / previewSpace.screenHeight
1815
19−
20− Rectangle {
16+ Wallpaper {
17+ source: previewSpace.background
2118 anchors.fill: parent
22− color: "blue"
2319
2420 Repeater {
25− id: workspaceRepeater
26− model: 15
21+ id: topLevelSurfaceRepeater
22+ model: visible ? topLevelSurfaceList : null
23+ delegate: Rectangle {
24+ width: surfaceItem.width
25+ height: surfaceItem.height + decorationHeight * previewScale
26+ x: model.window.position.x * previewScale
27+ y: (model.window.position.y - decorationHeight) * previewScale
28+ color: "blue"
29+ z: topLevelSurfaceRepeater.count - index
30+
31+ property int decorationHeight: units.gu(3)
32+
33+ WindowDecoration {
34+ width: surfaceItem.implicitWidth
35+ height: parent.decorationHeight
36+ transform: Scale {
37+ origin.x: 0
38+ origin.y: 0
39+ xScale: previewScale
40+ yScale: previewScale
41+ }
42+ title: model.window && model.window.surface ? model.window.surface.name : ""
43+ z: 3
44+ }
2745
28− delegate: Item {
29− x: index * previewSpace.screenWidth * previewScale
30− height: previewSpace.screenHeight * previewScale
31− width: previewSpace.screenWidth * previewScale
32− clip: true
46+ MirSurfaceItem {
47+ id: surfaceItem
48+ y: parent.decorationHeight * previewScale
49+ width: implicitWidth * previewScale
50+ height: implicitHeight * previewScale
51+ surfaceWidth: -1
52+ surfaceHeight: -1
53+ onImplicitHeightChanged: print("item", surfaceItem, "height changed", implicitHeight)
54+ surface: model.window.surface
55+ }
56+ }
57+ }
3358
34− Wallpaper {
35− source: previewSpace.background
36− anchors.fill: parent
59+ }
60+}
3761
3862 // Repeater {
3963 // id: topLevelSurfaceRepeater
@@ -73,8 +97,8 @@ UbuntuShape {
7397 // }
7498 // }
7599 // }
76− }
77− }
100+// }
101+// }
78102
79103
80104// MouseArea {
@@ -148,36 +172,36 @@ UbuntuShape {
148172// anchors.centerIn: parent
149173// }
150174// }
151− }
152−
153− FloatingFlickable {
154− id: flickable
155− anchors.fill: parent
156− contentWidth: workspaceRepeater.count * previewSpace.screenWidth * previewScale
157− property real progress: contentX / contentWidth
158− onContentXChanged: print("contentX:", contentX, "progress:", progress)
159− }
160−
161− MouseArea {
162− anchors.fill: parent
163− hoverEnabled: true
164− property int scrollAreaWidth: width / 3
165−
166− onMouseXChanged: {
167− var margins = flickable.width * 0.05;
168−
169− // do we need to scroll?
170− if (mouseX < scrollAreaWidth + margins) {
171− var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins));
172− var contentX = (1 - progress) * (flickable.contentWidth - flickable.width)
173− flickable.contentX = Math.max(0, Math.min(flickable.contentX, contentX))
174− }
175− if (mouseX > flickable.width - scrollAreaWidth) {
176− var progress = Math.min(1, (mouseX - (flickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins))
177− var contentX = progress * (flickable.contentWidth - flickable.width)
178− flickable.contentX = Math.min(flickable.contentWidth - flickable.width, Math.max(flickable.contentX, contentX))
179− }
180− }
181− }
182− }
183−}
175+// }
176+
177+// FloatingFlickable {
178+// id: flickable
179+// anchors.fill: parent
180+// contentWidth: workspaceRepeater.count * previewSpace.screenWidth * previewScale
181+// property real progress: contentX / contentWidth
182+// onContentXChanged: print("contentX:", contentX, "progress:", progress)
183+// }
184+
185+// MouseArea {
186+// anchors.fill: parent
187+// hoverEnabled: true
188+// property int scrollAreaWidth: width / 3
189+
190+// onMouseXChanged: {
191+// var margins = flickable.width * 0.05;
192+
193+// // do we need to scroll?
194+// if (mouseX < scrollAreaWidth + margins) {
195+// var progress = Math.min(1, (scrollAreaWidth + margins - mouseX) / (scrollAreaWidth - margins));
196+// var contentX = (1 - progress) * (flickable.contentWidth - flickable.width)
197+// flickable.contentX = Math.max(0, Math.min(flickable.contentX, contentX))
198+// }
199+// if (mouseX > flickable.width - scrollAreaWidth) {
200+// var progress = Math.min(1, (mouseX - (flickable.width - scrollAreaWidth)) / (scrollAreaWidth - margins))
201+// var contentX = progress * (flickable.contentWidth - flickable.width)
202+// flickable.contentX = Math.min(flickable.contentWidth - flickable.width, Math.max(flickable.contentX, contentX))
203+// }
204+// }
205+// }
206+// }
207+//}
qml/Stage/Spread/Workspaces.qml+11−7
@@ -1,11 +1,13 @@
11import QtQuick 2.4
22import Ubuntu.Components 1.3
3+import "MathUtils.js" as MathUtils
34
45Item {
56 id: root
67 implicitWidth: listView.count * (height * 16/9)
78
89 property var screen: null
10+ property var background // TODO: should be stored in the workspace data
911
1012 ListView {
1113 id: listView
@@ -29,7 +31,7 @@ Item {
2931 delegate: Item {
3032 objectName: "delegate" + index
3133 height: parent.height
32− width: dndArea.draggedIndex == index ? units.gu(5) : listView.itemWidth
34+ width: /*dndArea.draggedIndex == index ? units.gu(5) : */listView.itemWidth
3335 Behavior on width { UbuntuNumberAnimation {} }
3436
3537 property int itemX: -listView.contentX - listView.leftMargin + index * (listView.itemWidth + listView.spacing)
@@ -42,14 +44,14 @@ Item {
4244 if (index == 0) {
4345 if (distanceFromLeft < 0) {
4446 var progress = (distanceFromLeft + listView.foldingAreaWidth) / listView.foldingAreaWidth
45− return linearAnimation(1, -1, 0, maxAngle, Math.max(-1, Math.min(1, progress)));
47+ return MathUtils.linearAnimation(1, -1, 0, maxAngle, Math.max(-1, Math.min(1, progress)));
4648 }
4749 return 0
4850 }
4951 if (index == listView.count - 1) {
5052 if (distanceFromRight < 0) {
5153 var progress = (distanceFromRight + listView.foldingAreaWidth) / listView.foldingAreaWidth
52− return linearAnimation(1, -1, 0, -maxAngle, Math.max(-1, Math.min(1, progress)));
54+ return MathUtils.linearAnimation(1, -1, 0, -maxAngle, Math.max(-1, Math.min(1, progress)));
5355 }
5456 return 0
5557 }
@@ -57,11 +59,11 @@ Item {
5759 if (distanceFromLeft < listView.foldingAreaWidth) {
5860 // itemX : 10gu = p : 100
5961 var progress = distanceFromLeft / listView.foldingAreaWidth
60− return linearAnimation(1, -1, 0, maxAngle, Math.max(-1, Math.min(1, progress)));
62+ return MathUtils.linearAnimation(1, -1, 0, maxAngle, Math.max(-1, Math.min(1, progress)));
6163 }
6264 if (distanceFromRight < listView.foldingAreaWidth) {
6365 var progress = distanceFromRight / listView.foldingAreaWidth
64− return linearAnimation(1, -1, 0, -maxAngle, Math.max(-1, Math.min(1, progress)));
66+ return MathUtils.linearAnimation(1, -1, 0, -maxAngle, Math.max(-1, Math.min(1, progress)));
6567 }
6668 return 0
6769 }
@@ -116,9 +118,11 @@ Item {
116118 ]
117119
118120 WorkspacePreview {
119−
121+ height: listView.height
122+ width: listView.itemWidth
123+ background: root.background
124+ screenHeight: screen.physicalSize.height
120125 }
121−
122126 }
123127 }
124128}
qml/Stage/Stage.qml+1−1
@@ -346,7 +346,7 @@ FocusScope {
346346 readonly property real virtualKeyboardHeight: root.inputMethodRect.height
347347 }
348348
349− Component.onCompleted: priv.updateMainAndSideStageIndexes();
349+ Component.onCompleted: {priv.updateMainAndSideStageIndexes(); print("size", root.width, root.height)}
350350
351351 Connections {
352352 target: panelState
tests/mocks/Unity/Screens/plugin.cpp+2
@@ -33,6 +33,8 @@ void UnityScreensPlugin::registerTypes(const char* uri)
3333 Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Screens"));
3434
3535 qRegisterMetaType<QScreen*>("QScreen*");
36+ qRegisterMetaType<ScreenMode*>("ScreenMode*");
37+ qmlRegisterUncreatableType<ScreenMode>(uri, 0, 1, "ScreenMode", "ScreenMode is not creatable.");
3638
3739 qmlRegisterSingletonType<Screens>(uri, 0, 1, "Screens", screensSingleton);
3840 qmlRegisterType<ScreenWindow>(uri, 0, 1, "ScreenWindow");
tests/mocks/Unity/Screens/screens.cpp+39−42
@@ -18,11 +18,8 @@
1818
1919// Qt
2020#include <QGuiApplication>
21−#include <QScreen>
2221#include <QDebug>
2322
24−Q_DECLARE_METATYPE(QScreen*)
25−
2623Screens::Screens(QObject *parent) :
2724 QAbstractListModel(parent)
2825{
@@ -32,18 +29,18 @@ Screens::Screens(QObject *parent) :
3229 QPoint lastPoint(0,0);
3330 for (int i = 0; i < screenCount; ++i) {
3431 auto screen = new Screen();
35− screen->enabled = i == 0;
36− if (i == 0) {
37− screen->outputTypes = OutputTypes::LVDS;
38− } else {
39− screen->outputTypes = OutputTypes::HDMIA;
40− }
41− screen->name = QString("Monitor %1").arg(i);
42− screen->sizes = { QSize(640,480), QSize(1024,748), QSize(1280,1024), QSize(1440,900), QSize(1920,1080) };
43− screen->geometry = QRect(lastPoint.x(), lastPoint.y(), 1024, 786 );
32+ screen->m_active = i == 0;
33+ screen->m_name = QString("Monitor %1").arg(i);
34+ screen->m_position = QPoint(lastPoint.x(), lastPoint.y());
35+ screen->m_sizes.append(new ScreenMode(50, QSize(640,480)));
36+ screen->m_sizes.append(new ScreenMode(60, QSize(1280,1024)));
37+ screen->m_sizes.append(new ScreenMode(60, QSize(1440,900)));
38+ screen->m_sizes.append(new ScreenMode(60, QSize(1920,1080)));
39+ screen->m_currentModeIndex = 3;
40+ screen->m_physicalSize = QSize(800,568);
4441 m_screenList.append(screen);
4542
46− lastPoint.rx() += screen->geometry.width();
43+ lastPoint.rx() += screen->m_sizes[screen->m_currentModeIndex]->size.width();
4744 }
4845}
4946
@@ -57,13 +54,6 @@ QHash<int, QByteArray> Screens::roleNames() const
5754{
5855 QHash<int, QByteArray> roles;
5956 roles[ScreenRole] = "screen";
60− roles[OutputTypeRole] = "outputType";
61− roles[EnabledRole] = "enabled";
62− roles[NameRole] = "name";
63− roles[ScaleRole] = "scale";
64− roles[FormFactorRole] = "formFactor";
65− roles[GeometryRole] = "geometry";
66− roles[SizesRole] = "sizes";
6757 return roles;
6858}
6959
@@ -75,28 +65,7 @@ QVariant Screens::data(const QModelIndex &index, int role) const
7565
7666 switch(role) {
7767 case ScreenRole:
78− return QVariant::fromValue(m_screenList.at(index.row())->qScreen);
79− case OutputTypeRole:
80− return m_screenList.at(index.row())->outputTypes;
81− case EnabledRole:
82− return m_screenList.at(index.row())->enabled;
83− case NameRole:
84− return m_screenList.at(index.row())->name;
85− case ScaleRole:
86− return m_screenList.at(index.row())->scale;
87− case FormFactorRole:
88− return m_screenList.at(index.row())->formFactor;
89− case GeometryRole:
90− return m_screenList.at(index.row())->geometry;
91− case SizesRole:
92− {
93− QVariantList sizes;
94− auto availableSizes = m_screenList.at(index.row())->sizes;
95− Q_FOREACH(auto size, availableSizes) {
96− sizes.append(QVariant(size));
97− }
98− return sizes;
99− }
68+ return QVariant::fromValue(m_screenList.at(index.row()));
10069 }
10170
10271 return QVariant();
@@ -114,4 +83,32 @@ int Screens::count() const
11483
11584void Screens::activateScreen(int)
11685{
86+ qWarning("Not Implemented");
87+}
88+
89+Screen::Screen(QObject* parent)
90+ : QObject(parent)
91+{
92+}
93+
94+Screen::~Screen()
95+{
96+ qDeleteAll(m_sizes);
97+ m_sizes.clear();
98+}
99+
100+QQmlListProperty<ScreenMode> Screen::availableModes()
101+{
102+ return QQmlListProperty<ScreenMode>(this, m_sizes);
103+}
104+
105+Screen *Screen::beginConfiguration()
106+{
107+ qWarning("Not Implemented");
108+ return nullptr;
109+}
110+
111+void Screen::applyConfiguration()
112+{
113+ qWarning("Not Implemented");
117114}
tests/mocks/Unity/Screens/screens.h+65−9
@@ -19,6 +19,7 @@
1919
2020#include <QAbstractListModel>
2121#include <QScreen>
22+#include <QQmlListProperty>
2223
2324class Screen;
2425
@@ -90,17 +91,72 @@ private:
9091 QList<Screen *> m_screenList;
9192};
9293
93−class Screen
94+class ScreenMode : public QObject
9495{
96+ Q_OBJECT
97+ Q_PROPERTY(qreal refreshRate MEMBER refreshRate CONSTANT)
98+ Q_PROPERTY(QSize size MEMBER size CONSTANT)
99+public:
100+ ScreenMode() {}
101+ ScreenMode(qreal refreshRate, QSize size):refreshRate(refreshRate),size(size) {}
102+ ScreenMode(const ScreenMode& other)
103+ : QObject(nullptr),
104+ refreshRate{other.refreshRate},size{other.size}
105+ {}
106+
107+ qreal refreshRate;
108+ QSize size;
109+};
110+
111+class Screen : public QObject
112+{
113+ Q_OBJECT
114+
115+ Q_PROPERTY(bool active MEMBER m_active NOTIFY activeChanged)
116+
117+ Q_PROPERTY(bool used MEMBER m_used NOTIFY usedChanged)
118+ Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)
119+ Q_PROPERTY(Screens::OutputTypes outputType MEMBER m_outputType NOTIFY outputTypeChanged)
120+ Q_PROPERTY(float scale MEMBER m_scale NOTIFY scaleChanged)
121+ Q_PROPERTY(Screens::FormFactor formFactor MEMBER m_formFactor NOTIFY formFactorChanged)
122+ Q_PROPERTY(QPoint position MEMBER m_position NOTIFY positionChanged)
123+ Q_PROPERTY(uint currentModeIndex MEMBER m_currentModeIndex NOTIFY currentModeIndexChanged)
124+ Q_PROPERTY(QQmlListProperty<ScreenMode> availableModes READ availableModes NOTIFY availableModesChanged)
125+ Q_PROPERTY(QSizeF physicalSize MEMBER m_physicalSize NOTIFY physicalSizeChanged)
95126public:
96− Screens::OutputTypes outputTypes = Screens::Unknown;
97− QScreen *qScreen = nullptr;
98− bool enabled = false;
99− QString name = QString();
100− float scale = 1.0;
101− Screens::FormFactor formFactor = Screens::FormFactorMonitor;
102− QRect geometry;
103− QList<QSize> sizes;
127+ Screen(QObject* parent = 0);
128+ ~Screen();
129+
130+ QQmlListProperty<ScreenMode> availableModes();
131+
132+ Q_INVOKABLE Screen* beginConfiguration();
133+ Q_INVOKABLE void applyConfiguration();
134+
135+Q_SIGNALS:
136+ void activeChanged();
137+ void usedChanged();
138+ void nameChanged();
139+ void outputTypeChanged();
140+ void scaleChanged();
141+ void formFactorChanged();
142+ void positionChanged();
143+ void currentModeIndexChanged();
144+ void availableModesChanged();
145+ void physicalSizeChanged();
146+
147+public:
148+ bool m_active{false};
149+ bool m_used{true};
150+ QString m_name;
151+ Screens::OutputTypes m_outputType{Screens::Unknown};
152+ float m_scale{1.0};
153+ Screens::FormFactor m_formFactor{Screens::FormFactorMonitor};
154+ QPoint m_position;
155+ uint m_currentModeIndex{0};
156+ QList<ScreenMode*> m_sizes;
157+ QSizeF m_physicalSize;
104158};
105159
160+Q_DECLARE_METATYPE(ScreenMode)
161+
106162#endif // SCREENS_H
tests/mocks/Unity/Screens/screenwindow.cpp+7−4
@@ -21,12 +21,15 @@ ScreenWindow::ScreenWindow(QWindow *parent)
2121{
2222}
2323
24−QScreen *ScreenWindow::screen() const
24+Screen *ScreenWindow::screenWrapper() const
2525{
26− return QQuickWindow::screen();
26+ return m_screen.data();
2727}
2828
29−void ScreenWindow::setScreen(QScreen *screen)
29+void ScreenWindow::setScreenWrapper(Screen *screen)
3030{
31− QQuickWindow::setScreen(screen);
31+ if (m_screen != screen) {
32+ m_screen = screen;
33+ Q_EMIT screenWrapperChanged();
34+ }
3235}
tests/mocks/Unity/Screens/screenwindow.h+10−4
@@ -18,19 +18,25 @@
1818#define SCREENWINDOW_H
1919
2020#include <QQuickWindow>
21+#include <QPointer>
22+
23+#include "screens.h"
2124
2225class ScreenWindow : public QQuickWindow
2326{
2427 Q_OBJECT
25− Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChanged)
28+ Q_PROPERTY(Screen *screen READ screenWrapper WRITE setScreenWrapper NOTIFY screenWrapperChanged)
2629public:
2730 ScreenWindow(QWindow *parent = 0);
2831
29− QScreen *screen() const;
30− void setScreen(QScreen *screen);
32+ Screen *screenWrapper() const;
33+ void setScreenWrapper(Screen *screen);
3134
3235Q_SIGNALS:
33− void screenChanged(QScreen *screen);
36+ void screenWrapperChanged();
37+
38+private:
39+ QPointer<Screen> m_screen;
3440};
3541
3642#endif // SCREENWINDOW_H