File indexing completed on 2024-11-10 05:11:08
0001 /* 0002 * Copyright 2018 by Marco Martin <mart@kde.org> 0003 * 0004 * Licensed under the Apache License, Version 2.0 (the "License"); 0005 * you may not use this file except in compliance with the License. 0006 * You may obtain a copy of the License at 0007 * 0008 * http://www.apache.org/licenses/LICENSE-2.0 0009 * 0010 * Unless required by applicable law or agreed to in writing, software 0011 * distributed under the License is distributed on an "AS IS" BASIS, 0012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0013 * See the License for the specific language governing permissions and 0014 * limitations under the License. 0015 * 0016 */ 0017 0018 #pragma once 0019 0020 #include <QQuickItem> 0021 #include <QQmlParserStatus> 0022 #include <QQmlPropertyMap> 0023 #include <QPointer> 0024 0025 #include "sessiondatamap.h" 0026 #include "abstractskillview.h" 0027 0028 class MycroftController; 0029 0030 class DelegateLoader : public QObject { 0031 Q_OBJECT 0032 public: 0033 DelegateLoader(AbstractSkillView *parent); 0034 ~DelegateLoader(); 0035 0036 void init(const QString skillId, const QUrl &url); 0037 AbstractDelegate *delegate(); 0038 0039 void setFocus(bool focus); 0040 0041 QUrl translationsUrl() const; 0042 0043 Q_SIGNALS: 0044 void delegateCreated(); 0045 0046 private: 0047 void createObject(); 0048 0049 QString m_skillId; 0050 QUrl m_delegateUrl; 0051 bool m_focus = false; 0052 QQmlComponent *m_component = nullptr; 0053 AbstractSkillView *m_view; 0054 QPointer <AbstractDelegate> m_delegate; 0055 }; 0056 0057 class AbstractDelegate: public QQuickItem 0058 { 0059 Q_OBJECT 0060 Q_INTERFACES(QQmlParserStatus) 0061 0062 /** 0063 * The skill data sent by the server. 0064 */ 0065 Q_PROPERTY(SessionDataMap *sessionData READ sessionData CONSTANT) 0066 0067 /** 0068 * When true the delegate will always take the full screen width. (default false) 0069 */ 0070 Q_PROPERTY(bool fillWidth MEMBER m_fillWidth NOTIFY fillWidthChanged) 0071 0072 /** 0073 * The idle time after Mycroft stopped talking before the delegate wants to return to the resting face expressed in milliseconds. 0074 * The view may or may not follow this. 0075 * By default, it's 5 seconsa 0076 */ 0077 Q_PROPERTY(int timeout MEMBER m_timeout NOTIFY timeoutChanged) 0078 0079 /** 0080 * Source file for a skill-wide background (independent to the background item): it can be either an image or a QML file. 0081 * The view may or may not decide to display it, if different delegates of the same skill have different skillBackgrounds, it will fade between them when the current delegate changes. 0082 * Both relative paths and remote urls are supported 0083 */ 0084 Q_PROPERTY(QString skillBackgroundSource MEMBER m_backgroundSource NOTIFY skillBackgroundSourceChanged) 0085 0086 /** 0087 * Color to be used as an overlay for the skill-wide background. 0088 * If you are using skillBackgroundSource as well, consider using a semi transparent color. 0089 * By default is completely transparent on this implementation and Delegate has a slightly translucent black or white depending on the color scheme 0090 */ 0091 Q_PROPERTY(QColor skillBackgroundColorOverlay MEMBER m_skillBackgroundColorOverlay NOTIFY skillBackgroundColorOverlayChanged) 0092 0093 Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged) 0094 Q_PROPERTY(bool contentItemAutoHeight MEMBER m_contentItemAutoHeight NOTIFY contentItemAutoHeightChanged) 0095 Q_PROPERTY(bool contentItemAutoWidth MEMBER m_contentItemAutoWidth NOTIFY contentItemAutoWidthChanged) 0096 Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged) 0097 0098 /** 0099 * Padding adds a space between each edge of the content item and the background item, effectively controlling the size of the content item. 0100 */ 0101 Q_PROPERTY(int leftPadding READ leftPadding WRITE setLeftPadding NOTIFY leftPaddingChanged) 0102 Q_PROPERTY(int rightPadding READ rightPadding WRITE setRightPadding NOTIFY rightPaddingChanged) 0103 Q_PROPERTY(int topPadding READ topPadding WRITE setTopPadding NOTIFY topPaddingChanged) 0104 Q_PROPERTY(int bottomPadding READ bottomPadding WRITE setBottomPadding NOTIFY bottomPaddingChanged) 0105 0106 /** 0107 * Inset adds a space between the delagate edges and the background, adding an extra empty padding around the delegate 0108 */ 0109 Q_PROPERTY(int leftInset READ leftInset WRITE setLeftInset NOTIFY leftInsetChanged) 0110 Q_PROPERTY(int rightInset READ rightInset WRITE setRightInset NOTIFY rightInsetChanged) 0111 Q_PROPERTY(int topInset READ topInset WRITE setTopInset NOTIFY topInsetChanged) 0112 Q_PROPERTY(int bottomInset READ bottomInset WRITE setBottomInset NOTIFY bottomInsetChanged) 0113 0114 /** 0115 * The size of the contents: the size of this item minux the padding 0116 */ 0117 Q_PROPERTY(int contentWidth READ contentWidth NOTIFY contentWidthChanged) 0118 Q_PROPERTY(int contentHeight READ contentHeight NOTIFY contentHeightChanged) 0119 0120 Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) 0121 // Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") 0122 Q_CLASSINFO("DefaultProperty", "contentData") 0123 0124 public: 0125 AbstractDelegate(QQuickItem *parent = nullptr); 0126 ~AbstractDelegate(); 0127 0128 QQmlListProperty<QObject> contentData(); 0129 0130 /* 0131 * QML properties setters and getters 0132 */ 0133 QQuickItem *contentItem() const; 0134 void setContentItem(QQuickItem *item); 0135 0136 QQuickItem *background() const; 0137 void setBackground(QQuickItem *item); 0138 0139 /** 0140 * The only way the skill UI has to access the data sent by the server 0141 */ 0142 SessionDataMap *sessionData() const; 0143 0144 // Setters and getters for the padding 0145 int leftPadding() const; 0146 void setLeftPadding(int padding); 0147 0148 int topPadding() const; 0149 void setTopPadding(int padding); 0150 0151 int rightPadding() const; 0152 void setRightPadding(int padding); 0153 0154 int bottomPadding() const; 0155 void setBottomPadding(int padding); 0156 0157 // Setters and getters for the inset 0158 int leftInset() const; 0159 void setLeftInset(int inset); 0160 0161 int topInset() const; 0162 void setTopInset(int inset); 0163 0164 int rightInset() const; 0165 void setRightInset(int inset); 0166 0167 int bottomInset() const; 0168 void setBottomInset(int inset); 0169 0170 int contentWidth() const; 0171 int contentHeight() const; 0172 0173 /* 0174 * @internal All the following API is meant to be used only by AbstractSkillView during initialization, *NOT* QML from where is not accessible at all. 0175 */ 0176 0177 /** 0178 * The sessiondata is writable only by AbstractskillView internally, not from QML 0179 */ 0180 void setSessionData(SessionDataMap *data); 0181 0182 void setSkillView(AbstractSkillView *view); 0183 AbstractSkillView *skillView() const; 0184 0185 /** 0186 * @internal Url of the qml file that generated this instance 0187 */ 0188 void setQmlUrl(const QUrl &url); 0189 QUrl qmlUrl() const; 0190 0191 /** 0192 * @internal skill id this delegate belongs to 0193 */ 0194 void setSkillId(const QString &skillId); 0195 0196 public Q_SLOTS: 0197 /** 0198 * Trigger an event either for this skill or a system one 0199 * Is not possible to trigger events belonging to different skills 0200 */ 0201 void triggerGuiEvent(const QString &eventName, const QVariantMap ¶meters); 0202 QString skillId() const; 0203 0204 protected: 0205 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; 0206 protected: 0207 //void classBegin() override; 0208 void componentComplete() override; 0209 bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; 0210 void mousePressEvent(QMouseEvent *event) override; 0211 void keyReleaseEvent(QKeyEvent *event) override; 0212 void focusInEvent(QFocusEvent *event) override; 0213 0214 Q_SIGNALS: 0215 /** 0216 * Emitted when the server triggered an event. 0217 * It is guaranteed the event will be either a system event or an event belonging to our skill, but never to another skill. 0218 * The Skill writer can access this by implementing the following code on the root element of the delegate: 0219 * @code 0220 * onGuiEvent: { 0221 * switch (eventName) { 0222 * case "myevent1": 0223 * .... 0224 * } 0225 * } 0226 * @endcode 0227 * @param eventName the unique name for the event 0228 * @param data the data for this event in JSon form 0229 */ 0230 void guiEvent(const QString &eventName, const QVariantMap &data); 0231 0232 //QML property notifiers 0233 void skillBackgroundSourceChanged(); 0234 void skillBackgroundColorOverlayChanged(); 0235 void backgroundChanged(); 0236 void contentItemChanged(); 0237 void contentItemAutoWidthChanged(); 0238 void contentItemAutoHeightChanged(); 0239 void timeoutChanged(); 0240 void fillWidthChanged(); 0241 void leftPaddingChanged(); 0242 void rightPaddingChanged(); 0243 void topPaddingChanged(); 0244 void bottomPaddingChanged(); 0245 void leftInsetChanged(); 0246 void rightInsetChanged(); 0247 void topInsetChanged(); 0248 void bottomInsetChanged(); 0249 void contentWidthChanged(); 0250 void contentHeightChanged(); 0251 0252 private: 0253 void syncChildItemsGeometry(const QSizeF &size); 0254 //internal accessorts for the contentData QProperty 0255 static void contentData_append(QQmlListProperty<QObject> *prop, QObject *object); 0256 static qsizetype contentData_count(QQmlListProperty<QObject> *prop); 0257 static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index); 0258 static void contentData_clear(QQmlListProperty<QObject> *prop); 0259 0260 QPointer<QQuickItem> m_contentItem; 0261 QPointer<QQuickItem> m_backgroundItem; 0262 0263 //Internal implementation detail: this is used to reparent all items to contentItem 0264 QList<QObject *> m_contentData; 0265 0266 0267 //The main data from the Mycroft server 0268 QPointer<SessionDataMap> m_data; 0269 QPointer<AbstractSkillView> m_skillView; 0270 0271 QUrl m_qmlUrl; 0272 QString m_skillId; 0273 0274 QString m_backgroundSource; 0275 QColor m_skillBackgroundColorOverlay = Qt::transparent; 0276 int m_timeout = 5000; //Completely arbitrary 5 seconds of timeout 0277 bool m_fillWidth = false; 0278 0279 /** 0280 * Padding adds a space between each edge of the content item and the background item, effectively controlling the size of the content item. 0281 */ 0282 int m_leftPadding = 0; 0283 int m_rightPadding = 0; 0284 int m_topPadding = 0; 0285 int m_bottomPadding = 0; 0286 0287 int m_leftInset = 0; 0288 int m_rightInset = 0; 0289 int m_topInset = 0; 0290 int m_bottomInset = 0; 0291 0292 bool m_contentItemAutoWidth = true; 0293 bool m_contentItemAutoHeight = true; 0294 friend class ServerTest; 0295 }; 0296