diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 470603d0d0..3a5edb6844 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -328,16 +328,29 @@ class InputDialogListener : public ModalDialogListener { Q_OBJECT friend class OffscreenUi; - InputDialogListener(QQuickItem* queryBox) : ModalDialogListener(queryBox) { + InputDialogListener(QQuickItem* queryBox, bool custom = false) : ModalDialogListener(queryBox), _custom(custom) { if (_finished) { return; } connect(_dialog, SIGNAL(selected(QVariant)), this, SLOT(onSelected(const QVariant&))); } +private: + bool _custom { false }; private slots: void onSelected(const QVariant& result) { - _result = result; + if (_custom) { + if (result.isValid()) { + // We get a JSON encoded result, so we unpack it into a QVariant wrapping a QVariantMap + _result = QVariant(QJsonDocument::fromJson(result.toString().toUtf8()).object().toVariantMap()); + } + } else { + _result = result; + } + + auto offscreenUi = DependencyManager::get(); + emit offscreenUi->inputDialogResponse(_result); + offscreenUi->removeModalDialog(qobject_cast(this)); _finished = true; disconnect(_dialog); } @@ -391,6 +404,31 @@ QVariant OffscreenUi::getCustomInfo(const Icon icon, const QString& title, const return result; } +void OffscreenUi::getTextAsync(const Icon icon, const QString& title, const QString& label, const QString& text) { + DependencyManager::get()->inputDialogAsync(icon, title, label, text); +} + +void OffscreenUi::getItemAsync(const Icon icon, const QString& title, const QString& label, const QStringList& items, + int current, bool editable) { + + auto offscreenUi = DependencyManager::get(); + auto inputDialog = offscreenUi->createInputDialog(icon, title, label, current); + if (!inputDialog) { + return; + } + inputDialog->setProperty("items", items); + inputDialog->setProperty("editable", editable); + + InputDialogListener* inputDialogListener = new InputDialogListener(inputDialog); + offscreenUi->getModalDialogListeners().push_back(qobject_cast(inputDialogListener)); + + return; +} + +void OffscreenUi::getCustomInfoAsync(const Icon icon, const QString& title, const QVariantMap& config) { + DependencyManager::get()->customInputDialog(icon, title, config); +} + QVariant OffscreenUi::inputDialog(const Icon icon, const QString& title, const QString& label, const QVariant& current) { if (QThread::currentThread() != thread()) { QVariant result; @@ -406,6 +444,21 @@ QVariant OffscreenUi::inputDialog(const Icon icon, const QString& title, const Q return waitForInputDialogResult(createInputDialog(icon, title, label, current)); } +void OffscreenUi::inputDialogAsync(const Icon icon, const QString& title, const QString& label, const QVariant& current) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "inputDialogAsync", + Q_ARG(Icon, icon), + Q_ARG(QString, title), + Q_ARG(QString, label), + Q_ARG(QVariant, current)); + return; + } + + InputDialogListener* inputDialogListener = new InputDialogListener(createInputDialog(icon, title, label, current)); + QObject* inputDialog = qobject_cast(inputDialogListener); + _modalDialogListeners.push_back(inputDialog); +} + QVariant OffscreenUi::customInputDialog(const Icon icon, const QString& title, const QVariantMap& config) { if (QThread::currentThread() != thread()) { QVariant result; @@ -426,6 +479,21 @@ QVariant OffscreenUi::customInputDialog(const Icon icon, const QString& title, c return result; } +void OffscreenUi::customInputDialogAsync(const Icon icon, const QString& title, const QVariantMap& config) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "customInputDialogAsync", + Q_ARG(Icon, icon), + Q_ARG(QString, title), + Q_ARG(QVariantMap, config)); + return; + } + + InputDialogListener* inputDialogListener = new InputDialogListener(createCustomInputDialog(icon, title, config), true); + QObject* inputDialog = qobject_cast(inputDialogListener); + _modalDialogListeners.push_back(inputDialog); + return; +} + void OffscreenUi::togglePinned() { bool invokeResult = QMetaObject::invokeMethod(_desktop, "togglePinned"); if (!invokeResult) { @@ -950,6 +1018,10 @@ void OffscreenUi::assetDialogAsync(const QVariantMap& properties) { return; } +QList &OffscreenUi::getModalDialogListeners() { + return _modalDialogListeners; +} + QString OffscreenUi::assetOpenDialog(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { // ATP equivalent of fileOpenDialog(). if (QThread::currentThread() != thread()) { diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index a3529da89c..716e598291 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -173,7 +173,9 @@ public: static void getOpenAssetNameAsync(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); Q_INVOKABLE QVariant inputDialog(const Icon icon, const QString& title, const QString& label = QString(), const QVariant& current = QVariant()); + Q_INVOKABLE void inputDialogAsync(const Icon icon, const QString& title, const QString& label = QString(), const QVariant& current = QVariant()); Q_INVOKABLE QVariant customInputDialog(const Icon icon, const QString& title, const QVariantMap& config); + Q_INVOKABLE void customInputDialogAsync(const Icon icon, const QString& title, const QVariantMap& config); QQuickItem* createInputDialog(const Icon icon, const QString& title, const QString& label, const QVariant& current); QQuickItem* createCustomInputDialog(const Icon icon, const QString& title, const QVariantMap& config); QVariant waitForInputDialogResult(QQuickItem* inputDialog); @@ -191,16 +193,35 @@ public: return getItem(OffscreenUi::ICON_NONE, title, label, items, current, editable, ok); } + // Compatibility with QInputDialog::getText + static void getTextAsync(void* ignored, const QString & title, const QString & label, + QLineEdit::EchoMode mode = QLineEdit::Normal, const QString & text = QString(), bool * ok = 0, + Qt::WindowFlags flags = 0, Qt::InputMethodHints inputMethodHints = Qt::ImhNone) { + return getTextAsync(OffscreenUi::ICON_NONE, title, label, text); + } + // Compatibility with QInputDialog::getItem + static void getItemAsync(void *ignored, const QString & title, const QString & label, const QStringList & items, + int current = 0, bool editable = true, bool * ok = 0, Qt::WindowFlags flags = 0, + Qt::InputMethodHints inputMethodHints = Qt::ImhNone) { + return getItemAsync(OffscreenUi::ICON_NONE, title, label, items, current, editable); + } + static QString getText(const Icon icon, const QString & title, const QString & label, const QString & text = QString(), bool * ok = 0); static QString getItem(const Icon icon, const QString & title, const QString & label, const QStringList & items, int current = 0, bool editable = true, bool * ok = 0); static QVariant getCustomInfo(const Icon icon, const QString& title, const QVariantMap& config, bool* ok = 0); + static void getTextAsync(const Icon icon, const QString & title, const QString & label, const QString & text = QString()); + static void getItemAsync(const Icon icon, const QString & title, const QString & label, const QStringList & items, int current = 0, bool editable = true); + static void getCustomInfoAsync(const Icon icon, const QString& title, const QVariantMap& config); unsigned int getMenuUserDataId() const; + QList &getModalDialogListeners(); + signals: void showDesktop(); void response(QMessageBox::StandardButton response); void fileDialogResponse(QString response); void assetDialogResponse(QString response); + void inputDialogResponse(QVariant response); public slots: void removeModalDialog(QObject* modal);