RiveQtQuickPlugin
rivestatemachineinput.h
1 // SPDX-FileCopyrightText: 2023 Jeremias Bosch <jeremias.bosch@basyskom.com>
2 // SPDX-FileCopyrightText: 2023 basysKom GmbH
3 //
4 // SPDX-License-Identifier: LGPL-3.0-or-later
5 #pragma once
6 
7 #include "qqmlcontext.h"
8 #include <QQuickItem>
9 
10 #include <rive/core.hpp>
11 #include <rive/animation/state_machine_instance.hpp>
12 
13 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
14 # include <QtQml/qqmlregistration.h>
15 #endif
16 
118 class DynamicPropertyHolder : public QObject
119 {
120  Q_OBJECT
121  Q_PROPERTY(QVariant value READ value NOTIFY valueChanged)
122 
123 private:
124  QVariant m_value;
125 
126  QJSValue m_toString;
127 
128 public:
129  explicit DynamicPropertyHolder(QObject *parent = nullptr)
130  : QObject(parent)
131  {
132  }
133 
134  QVariant value() const { return m_value; }
135 
136  void setValue(const QVariant &value)
137  {
138  if (m_value != value) {
139  m_value = value;
140  emit valueChanged();
141  }
142  }
143 
144 signals:
145  void valueChanged();
146 };
147 
148 class QQmlEngine;
149 class RiveStateMachineInput : public QObject, public QQmlParserStatus
150 {
151  Q_OBJECT
152  Q_INTERFACES(QQmlParserStatus)
153 
154  QML_NAMED_ELEMENT(RiveStateMachineInput)
155 
156  Q_PROPERTY(QVariantList riveInputs READ riveInputs NOTIFY riveInputsChanged)
157 public:
158  enum class RivePropertyType : short
159  {
160  RiveNumber,
161  RiveBoolean,
162  RiveTrigger
163  };
164  Q_ENUM(RivePropertyType)
165 
166  RiveStateMachineInput(QObject *parent = nullptr);
167 
168  void generateStringInterface();
169  bool hasDirtyStateMachine() const { return m_dirty; }
170 
171  Q_INVOKABLE void setRiveProperty(const QString &propertyName, const QVariant &value);
172  Q_INVOKABLE QVariant getRiveProperty(const QString &propertyName) const;
173  Q_INVOKABLE void callTrigger(const QString &triggerName);
174  Q_INVOKABLE QObject *listenTo(const QString &name);
175 
176  void setStateMachineInstance(rive::StateMachineInstance *stateMachineInstance);
177  QVariantList riveInputs() const;
178 
179  const QString &riveQtArtboardName() const;
180  void setRiveQtArtboardName(const QString &newRiveQtArtboardName);
181 
182  void initializeInternal();
183 public slots:
184  void updateValues();
185 
186 signals:
187  void riveInputsChanged();
188 
189 private slots:
190  void activateTrigger();
191  void handlePropertyChanged();
192 
193 protected:
194  void classBegin() override;
195  void componentComplete() override;
196 
197 private:
198  QString cleanUpRiveName(const QString &name);
199 
200  // we ignore properties with those names as they will
201  // conflict with JS/QML environment
202  const QStringList reservedWords = { "await", "break", "case", "catch",
203  "class", "const", "continue", "debugger",
204  "default", "delete", "do", "else",
205  "export", "extends", "finally", "for",
206  "function", "if", "import", "in",
207  "instanceof", "new", "return", "super",
208  "switch", "this", "throw", "try",
209  "typeof", "var", "void", "while",
210  "with", "yield", "enum", "implements",
211  "interface", "let", "package", "private",
212  "protected", "public", "static", "riveQtArtboardName",
213  "riveInputs" };
214  void connectStateMachineToProperties();
215  rive::StateMachineInstance *m_stateMachineInstance { nullptr };
216  QMap<QString, rive::SMIInput *> m_inputMap;
217 
218  bool m_dirty { false };
219  bool m_isCompleted { false };
220  bool m_hasGeneratedStringInterface { false };
221 
222  QVariantMap m_generatedRivePropertyMap;
223  QMap<QString, DynamicPropertyHolder *> m_dynamicProperties;
224 
225  QPair<bool, QVariant> updateProperty(const QString &propertyName, const QVariant &propertyValue);
226 };
227 
228 Q_DECLARE_METATYPE(RiveStateMachineInput::RivePropertyType)
Interface for binding QML properties to Rive's state machine.
Definition: rivestatemachineinput.h:150