Merge lp:~zsombi/ubuntu-ui-toolkit/colorSelector into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Work in progress
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/colorSelector
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 564 lines (+414/-4) (has conflicts)
9 files modified
debian/libubuntutoolkit5-dev.install (+2/-0)
src/Ubuntu/Components/plugin/ucstyleditembase.cpp (+95/-1)
src/Ubuntu/Components/plugin/ucstyleditembase.h (+15/-0)
src/Ubuntu/Components/plugin/ucstyleditembase_p.h (+8/-0)
src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro (+4/-2)
src/Ubuntu/UbuntuToolkit/propertybinding.cpp (+78/-0)
src/Ubuntu/UbuntuToolkit/propertybinding.h (+207/-0)
tests/unit/plugin_dependency.pri (+4/-0)
tests/unit_x11/tst_subtheming/tst_subtheming.pro (+1/-1)
Text conflict in tests/unit/plugin_dependency.pri
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/colorSelector
Reviewer Review Type Date Requested Status
Ubuntu SDK team Pending
Review via email: mp+288301@code.launchpad.net
To post a comment you must log in.
1884. By Zsombor Egri

introduce PropertyBinding

1885. By Zsombor Egri

stage, unbildable

Unmerged revisions

1885. By Zsombor Egri

stage, unbildable

1884. By Zsombor Egri

introduce PropertyBinding

1883. By Zsombor Egri

bug

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/libubuntutoolkit5-dev.install'
2--- debian/libubuntutoolkit5-dev.install 2016-03-04 11:58:12 +0000
3+++ debian/libubuntutoolkit5-dev.install 2016-03-15 11:52:58 +0000
4@@ -2,6 +2,8 @@
5 usr/include/*/qt5/UbuntuToolkit/ColorUtils
6 usr/include/*/qt5/UbuntuToolkit/Tree
7 usr/include/*/qt5/UbuntuToolkit/UbuntuToolkit
8+usr/include/*/qt5/UbuntuToolkit/PropertyBinding
9+usr/include/*/qt5/UbuntuToolkit/propertybinding.h
10 usr/include/*/qt5/UbuntuToolkit/UbuntuToolkitDepends
11 usr/include/*/qt5/UbuntuToolkit/UbuntuToolkitVersion
12 usr/include/*/qt5/UbuntuToolkit/asyncloader.h
13
14=== modified file 'src/Ubuntu/Components/plugin/ucstyleditembase.cpp'
15--- src/Ubuntu/Components/plugin/ucstyleditembase.cpp 2016-02-29 16:50:41 +0000
16+++ src/Ubuntu/Components/plugin/ucstyleditembase.cpp 2016-03-15 11:52:58 +0000
17@@ -29,6 +29,10 @@
18 : oldParentItem(Q_NULLPTR)
19 , styleComponent(Q_NULLPTR)
20 , styleItem(Q_NULLPTR)
21+ , highlighted(Q_NULLPTR)
22+ , focused(Q_NULLPTR)
23+ , selected(Q_NULLPTR)
24+ , componentState(UCStyledItemBase::Undefined)
25 , styleVersion(0)
26 , keyNavigationFocus(false)
27 , activeFocusOnPress(false)
28@@ -62,6 +66,61 @@
29 QObject::connect(q, &QQuickItem::activeFocusOnTabChanged, q, &UCStyledItemBase::activeFocusOnTabChanged2);
30 }
31
32+// initializes state builders
33+void UCStyledItemBasePrivate::setupHighlightedStateBinging()
34+{
35+// Q_Q(UCStyledItemBase);
36+// const QMetaObject *mo = q->metaObject();
37+// // detect highlight setup
38+// if (mo->indexOfProperty("pressed") > 0) {
39+// QMetaMethod change = mo->method(mo->indexOfSignal("pressedChanged()"));
40+// auto getter = [=] ()->bool {
41+// return QQmlProperty::read(q, "pressed", qmlContext(q)).toBool();
42+// };
43+// highlighted = new UbuntuToolkit::PropertyBinding<bool>(
44+// getter,
45+// std::bind(&UCStyledItemBase::componentStateChanged, q),
46+// {UbuntuToolkit::ValueBinding(q, change)});
47+// } else if (mo->indexOfProperty("highlighted") > 0) {
48+// QMetaMethod change = mo->method(mo->indexOfSignal("highlightedChanged()"));
49+// auto getter = [=] ()->bool {
50+// return QQmlProperty::read(q, "highlighted", qmlContext(q)).toBool();
51+// };
52+// highlighted = new UbuntuToolkit::PropertyBinding<bool>(
53+// getter,
54+// std::bind(&UCStyledItemBase::componentStateChanged, q),
55+// {UbuntuToolkit::ValueBinding(q, change)});
56+// }
57+}
58+
59+void UCStyledItemBasePrivate::setupFocusedStateBinging()
60+{
61+ Q_Q(UCStyledItemBase);
62+
63+ auto b2ObjectGetter = [q]() -> QObject* {
64+ return q->window();
65+ };
66+ UbuntuToolkit::Binding *b2 = new UbuntuToolkit::ExpressionBinding<QObject*>
67+ (b2ObjectGetter, &QQuickWindow::activeFocusItemChanged);
68+
69+ UbuntuToolkit::Binding *b1;
70+ auto b1Updater = [&b1]() {
71+ b1->reconnect();
72+ b1->update();
73+ };
74+ b1 = new UbuntuToolkit::UpdateBinding(q, &QQuickItem::windowChanged, b1Updater, {b2});
75+
76+ auto getter = [=] () -> bool {
77+ return q->window() && q->window()->activeFocusItem() == q;
78+ };
79+ focused = new UbuntuToolkit::BindingExpression<bool>(getter, {b2});
80+}
81+
82+void UCStyledItemBasePrivate::setupSelectedStateBinging()
83+{
84+
85+}
86+
87
88 void UCStyledItemBasePrivate::setFocusable(bool focus)
89 {
90@@ -480,6 +539,35 @@
91 d->loadStyleItem();
92 }
93
94+/*!
95+ * \qmlproperty ComponentState StyledItem::componentState
96+ * \readonly
97+ * \since Ubuntu.Components 1.3
98+ * The property reports the current state of the component.
99+ */
100+UCStyledItemBase::ComponentState UCStyledItemBase::componentState()
101+{
102+ Q_D(const UCStyledItemBase);
103+ if (isEnabled()) {
104+ if (d->highlighted && d->highlighted->value()) {
105+ return Highlighted;
106+ }
107+ if (d->focused && d->focused->value()) {
108+ return Focused;
109+ }
110+ if (d->selected && d->selected->value()) {
111+ return Selected;
112+ }
113+ return Normal;
114+ } else if (d->selected && d->selected->value()) {
115+ return SelectedDisabled;
116+ } else {
117+ return Disabled;
118+ }
119+
120+ return Undefined;
121+}
122+
123 QString UCStyledItemBasePrivate::propertyForVersion(quint16 version) const
124 {
125 switch (MINOR_VERSION(version)) {
126@@ -510,10 +598,16 @@
127 * The member defaults to true. Additionally, the focus scope flag must
128 * be set before the parentItem is set and child items are added.
129 */
130- if (d_func()->isFocusScope) {
131+ Q_D(UCStyledItemBase);
132+ if (d->isFocusScope) {
133 setFlag(QQuickItem::ItemIsFocusScope);
134 }
135 QQuickItem::classBegin();
136+
137+ // build state transitioners
138+ d->setupHighlightedStateBinging();
139+ d->setupFocusedStateBinging();
140+ d->setupSelectedStateBinging();
141 }
142
143 void UCStyledItemBase::componentComplete()
144
145=== modified file 'src/Ubuntu/Components/plugin/ucstyleditembase.h'
146--- src/Ubuntu/Components/plugin/ucstyleditembase.h 2016-01-16 15:52:56 +0000
147+++ src/Ubuntu/Components/plugin/ucstyleditembase.h 2016-03-15 11:52:58 +0000
148@@ -25,6 +25,7 @@
149 class UCStyledItemBasePrivate;
150 class UCTheme;
151 class UCStyleHints;
152+class StyledItemAttached;
153 class UCStyledItemBase : public QQuickItem, public UCThemingExtension
154 {
155 Q_OBJECT
156@@ -45,7 +46,19 @@
157 Q_PRIVATE_PROPERTY(UCStyledItemBase::d_func(), QQuickItem *__styleInstance READ styleInstance NOTIFY styleInstanceChanged FINAL DESIGNABLE false)
158 Q_PRIVATE_PROPERTY(UCStyledItemBase::d_func(), QString styleName READ styleName WRITE setStyleName NOTIFY styleNameChanged FINAL REVISION 2)
159 Q_PROPERTY(UCTheme *theme READ getTheme WRITE setTheme RESET resetTheme NOTIFY themeChanged FINAL REVISION 2)
160+ Q_PROPERTY(ComponentState componentState READ componentState NOTIFY componentStateChanged FINAL REVISION 2)
161+ Q_ENUMS(ComponentState)
162 public:
163+ enum ComponentState {
164+ Undefined,
165+ Normal,
166+ Highlighted,
167+ Focused,
168+ Selected,
169+ Disabled,
170+ SelectedDisabled
171+ };
172+
173 explicit UCStyledItemBase(QQuickItem *parent = 0);
174
175 virtual bool keyNavigationFocus() const;
176@@ -53,6 +66,7 @@
177 void setActiveFocusOnPress(bool value);
178 bool activeFocusOnTab2() const;
179 void setActiveFocusOnTab2(bool value);
180+ ComponentState componentState();
181
182 public Q_SLOTS:
183 Q_REVISION(1) bool requestFocus(Qt::FocusReason reason = Qt::OtherFocusReason);
184@@ -65,6 +79,7 @@
185 Q_REVISION(1) void activeFocusOnTabChanged2();
186 Q_REVISION(2) void themeChanged();
187 Q_REVISION(2) void styleNameChanged();
188+ Q_REVISION(2) void componentStateChanged();
189
190 protected:
191 UCStyledItemBase(UCStyledItemBasePrivate &, QQuickItem *parent);
192
193=== modified file 'src/Ubuntu/Components/plugin/ucstyleditembase_p.h'
194--- src/Ubuntu/Components/plugin/ucstyleditembase_p.h 2016-01-16 10:55:26 +0000
195+++ src/Ubuntu/Components/plugin/ucstyleditembase_p.h 2016-03-15 11:52:58 +0000
196@@ -23,6 +23,7 @@
197 #include "ucstyleditembase.h"
198 #include "ucthemingextension.h"
199 #include "ucimportversionchecker_p.h"
200+#include <UbuntuToolkit/PropertyBinding>
201
202 class QQuickMouseArea;
203 class UCStyledItemBase;
204@@ -41,6 +42,9 @@
205 UCStyledItemBasePrivate();
206 virtual ~UCStyledItemBasePrivate();
207 void init();
208+ virtual void setupHighlightedStateBinging();
209+ virtual void setupFocusedStateBinging();
210+ virtual void setupSelectedStateBinging();
211
212 virtual void setFocusable(bool focus);
213 bool isParentFocusable();
214@@ -68,6 +72,10 @@
215 QQuickItem *oldParentItem;
216 QQmlComponent *styleComponent;
217 QQuickItem *styleItem;
218+ UbuntuToolkit::BindingExpression<bool> *highlighted;
219+ UbuntuToolkit::BindingExpression<bool> *focused;
220+ UbuntuToolkit::BindingExpression<bool> *selected;
221+ UCStyledItemBase::ComponentState componentState;
222 quint16 styleVersion;
223 bool keyNavigationFocus:1;
224 bool activeFocusOnPress:1;
225
226=== modified file 'src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro'
227--- src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro 2016-02-25 14:35:59 +0000
228+++ src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro 2016-03-15 11:52:58 +0000
229@@ -17,9 +17,11 @@
230 ubuntutoolkitglobal.h \
231 tree.h \
232 asyncloader.h \
233- asyncloader_p.h
234+ asyncloader_p.h \
235+ propertybinding.h
236
237 SOURCES += \
238 colorutils.cpp \
239 tree.cpp \
240- asyncloader.cpp
241+ asyncloader.cpp \
242+ propertybinding.cpp
243
244=== added file 'src/Ubuntu/UbuntuToolkit/propertybinding.cpp'
245--- src/Ubuntu/UbuntuToolkit/propertybinding.cpp 1970-01-01 00:00:00 +0000
246+++ src/Ubuntu/UbuntuToolkit/propertybinding.cpp 2016-03-15 11:52:58 +0000
247@@ -0,0 +1,78 @@
248+/*
249+ * Copyright 2016 Canonical Ltd.
250+ *
251+ * This program is free software; you can redistribute it and/or modify
252+ * it under the terms of the GNU Lesser General Public License as published by
253+ * the Free Software Foundation; version 3.
254+ *
255+ * This program is distributed in the hope that it will be useful,
256+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
257+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
258+ * GNU Lesser General Public License for more details.
259+ *
260+ * You should have received a copy of the GNU Lesser General Public License
261+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
262+ *
263+ * Author: Zsombor Egri <zsombor.egri@canonical.com>
264+ */
265+
266+#include "propertybinding.h"
267+#include <QtCore/QMetaMethod>
268+
269+namespace UbuntuToolkit {
270+
271+/******************************************************************************
272+ * Binding
273+ */
274+
275+Binding::Binding(const Bindings &bindings, Binding *parent)
276+ : m_parent(parent)
277+{
278+ for (Binding *b : bindings) {
279+ addChild(b);
280+ }
281+}
282+
283+Binding::~Binding()
284+{
285+ if (m_parent) {
286+ int idx = m_parent->m_children.indexOf(this);
287+ if (idx >= 0) {
288+ m_parent->m_children.remove(idx);
289+ }
290+ }
291+}
292+
293+Binding *Binding::parent()
294+{
295+ return m_parent;
296+}
297+void Binding::addChild(Binding *binding)
298+{
299+ m_children.append(binding);
300+ binding->m_parent = this;
301+}
302+
303+void Binding::connectExpression(BindingUpdateExpression *expression)
304+{
305+ m_expression = expression;
306+ // TODO: connect the binding to the expression's update()
307+}
308+
309+void Binding::reconnect()
310+{
311+ Q_FOREACH(Binding *b, m_children) {
312+ b->reconnect();
313+ }
314+}
315+
316+
317+/******************************************************************************
318+ * UpdateNotifier
319+ */
320+
321+/******************************************************************************
322+ * Binding
323+ */
324+
325+} // namespace
326
327=== added file 'src/Ubuntu/UbuntuToolkit/propertybinding.h'
328--- src/Ubuntu/UbuntuToolkit/propertybinding.h 1970-01-01 00:00:00 +0000
329+++ src/Ubuntu/UbuntuToolkit/propertybinding.h 2016-03-15 11:52:58 +0000
330@@ -0,0 +1,207 @@
331+/*
332+ * Copyright 2016 Canonical Ltd.
333+ *
334+ * This program is free software; you can redistribute it and/or modify
335+ * it under the terms of the GNU Lesser General Public License as published by
336+ * the Free Software Foundation; version 3.
337+ *
338+ * This program is distributed in the hope that it will be useful,
339+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
340+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
341+ * GNU Lesser General Public License for more details.
342+ *
343+ * You should have received a copy of the GNU Lesser General Public License
344+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
345+ *
346+ * Author: Zsombor Egri <zsombor.egri@canonical.com>
347+ */
348+
349+#ifndef PROPERTYBINDING_H
350+#define PROPERTYBINDING_H
351+
352+#include <QtCore/QObject>
353+#include <QtQml/QQmlProperty>
354+#include <functional>
355+#include <initializer_list>
356+#include <tuple>
357+#include "ubuntutoolkitglobal.h"
358+
359+namespace UbuntuToolkit {
360+
361+class UBUNTUTOOLKIT_EXPORT BindingUpdateExpression
362+{
363+public:
364+ virtual void update() {}
365+};
366+
367+class UBUNTUTOOLKIT_EXPORT Binding
368+{
369+public:
370+ typedef std::initializer_list<Binding*> Bindings;
371+
372+ explicit Binding(const Bindings &bindings = {}, Binding *parent = 0);
373+ virtual ~Binding();
374+
375+ void connectExpression(BindingUpdateExpression *expression);
376+
377+ // FIXME perhaps call it as update? would collide with the BindingExpression's update
378+ virtual void reconnect();
379+
380+ Binding *parent();
381+protected:
382+ BindingUpdateExpression *m_expression = nullptr;
383+ QMetaObject::Connection *m_connection = nullptr;
384+ QVarLengthArray<Binding*, 4> m_children;
385+
386+private:
387+ Binding *m_parent;
388+ void addChild(Binding *binding);
389+};
390+
391+//
392+// Signal to slot connector
393+//
394+typedef std::function<QMetaObject::Connection(QObject *s, QObject *r)> Connector;
395+template <typename Sender, typename Receiver, typename Signal, typename Slot>
396+Connector createConnector (Signal sig, Slot sl)
397+{
398+ return [sig, sl] (QObject *s, QObject *r){
399+ Sender *sender = static_cast<Sender *>(s);
400+ Receiver *receiver = static_cast<Receiver *>(r);
401+
402+ return QObject::connect(sender, sig, receiver, sl);
403+ };
404+}
405+
406+//
407+// Signal to lambda connector
408+//
409+typedef std::function<QMetaObject::Connection(QObject *s)> LConnector;
410+template <typename Sender, typename Signal, typename Receiver>
411+LConnector createConnector (Signal sig, Receiver rec)
412+{
413+ return [sig, rec] (QObject *s){
414+ Sender *sender = static_cast<Sender *>(s);
415+
416+ return QObject::connect(sender, sig, rec);
417+ };
418+}
419+//
420+// UpdateBinding (or maybe ReconnectBinding?)
421+//
422+class UBUNTUTOOLKIT_EXPORT UpdateBinding : public Binding
423+{
424+public:
425+ UpdateBinding(QObject *sender, Signal signal, const Bindings &bindings = {}, Binding *parent = 0)
426+ : Binding(bindings, parent)
427+ , m_sender(sender)
428+ , m_signal(signal)
429+ {
430+ // TODO: connect m_signal to reconnect()
431+ }
432+
433+ void reconnect() override
434+ {
435+ // reconnect kids first
436+ Binding::reconnect();
437+ // ivoke expression's update too
438+ m_expression->update();
439+ }
440+
441+private:
442+ QObject *m_sender;
443+ Signal m_signal;
444+};
445+
446+//
447+// PropertyBinding
448+//
449+template<typename T>
450+class UBUNTUTOOLKIT_EXPORT ExpressionBinding : public Binding
451+{
452+public:
453+ typedef std::function<T()> Expression;
454+
455+ explicit ExpressionBinding(Expression expression, LConnector connector, const Bindings &bindings = {}, Binding *parent = 0)
456+ : Binding(bindings, parent)
457+ , m_expression(expression)
458+ {
459+// m_signal = createConnector<QObject>(Signal, &Binding::update);
460+ }
461+
462+ void reconnect() override
463+ {
464+ if (connection) {
465+ QObject::disconnect(*connection);
466+ }
467+ // TODO oupdate connection
468+ Binding::reconnect();
469+ }
470+private:
471+ Expression m_expression;
472+ LConnector m_signal;
473+};
474+
475+
476+//
477+// BindingExpression
478+//
479+
480+template<typename T>
481+class UBUNTUTOOLKIT_EXPORT BindingExpression : private BindingUpdateExpression
482+{
483+public:
484+ typedef T ElementType;
485+
486+ typedef std::function<ElementType()> GetterFunc;
487+
488+ typedef std::function<void()> BindingSignal;
489+
490+ explicit BindingExpression(GetterFunc getter, BindingSignal signal, const Binding::Bindings &bindings)
491+ : getter(getter)
492+ , signal(signal)
493+ , propertyValue(getter())
494+ {
495+ init(bindings);
496+ }
497+ ~BindingExpression()
498+ {
499+ qDeleteAll(bindings);
500+ bindings.clear();
501+ }
502+
503+ T value()
504+ {
505+ return propertyValue;
506+ }
507+
508+private:
509+ void init(const Binding::Bindings &bindings)
510+ {
511+ Q_UNUSED(bindings);
512+ for (Binding *b : bindings) {
513+ this->bindings.append(b);
514+ // hook update
515+ b->connectExpression(this);
516+ }
517+ }
518+
519+ void update() override
520+ {
521+ ElementType newValue = getter();
522+ if (newValue == propertyValue) {
523+ return;
524+ }
525+ propertyValue = newValue;
526+ signal();
527+ }
528+
529+ GetterFunc getter;
530+ QVarLengthArray<Binding*, 4 > bindings;
531+ BindingSignal signal;
532+ ElementType propertyValue;
533+};
534+
535+} // namespace UbuntuToolkit
536+
537+#endif // PROPERTYBINDING_H
538
539=== modified file 'tests/unit/plugin_dependency.pri'
540--- tests/unit/plugin_dependency.pri 2016-03-10 05:25:02 +0000
541+++ tests/unit/plugin_dependency.pri 2016-03-15 11:52:58 +0000
542@@ -9,7 +9,11 @@
543 LIBS += -L$$PLUGIN_BLD/Components -lUbuntuComponents
544 LIBS += -L$$PLUGIN_BLD/Test -lUbuntuTest
545 LIBS += -L$${ROOT_BUILD_DIR}/lib -lUbuntuGestures
546+<<<<<<< TREE
547 LIBS += -L$$PLUGIN_BLD/UbuntuToolkit -lUbuntuToolkit
548+=======
549+LIBS += -L$${ROOT_BUILD_DIR}/lib -lUbuntuToolkit
550+>>>>>>> MERGE-SOURCE
551 DEFINES += QUICK_TEST_SOURCE_DIR=\"\\\"$$_PRO_FILE_PWD_\\\"\"
552 QMAKE_CXXFLAGS += -Werror
553
554
555=== modified file 'tests/unit_x11/tst_subtheming/tst_subtheming.pro'
556--- tests/unit_x11/tst_subtheming/tst_subtheming.pro 2016-03-14 17:08:59 +0000
557+++ tests/unit_x11/tst_subtheming/tst_subtheming.pro 2016-03-15 11:52:58 +0000
558@@ -1,5 +1,5 @@
559 include(../test-include.pri)
560-QT += core-private qml-private quick-private gui-private
561+QT += core-private qml-private quick-private gui-private UbuntuToolkit
562 SOURCES += tst_subtheming.cpp
563
564 OTHER_FILES += \

Subscribers

People subscribed via source and target branches