Update input dialog to support choice selection

This commit is contained in:
Brad Davis 2016-01-28 21:19:21 -08:00
parent 35211b7475
commit c80193635b
4 changed files with 115 additions and 40 deletions

View file

@ -252,9 +252,9 @@ FocusScope {
return messageDialogBuilder.createObject(desktop, properties); return messageDialogBuilder.createObject(desktop, properties);
} }
Component { id: queryDialogBuilder; QueryDialog { } } Component { id: inputDialogBuilder; QueryDialog { } }
function queryBox(properties) { function inputDialog(properties) {
return queryDialogBuilder.createObject(desktop, properties); return inputDialogBuilder.createObject(desktop, properties);
} }
Component { id: fileDialogBuilder; FileDialog { } } Component { id: fileDialogBuilder; FileDialog { } }

View file

@ -16,9 +16,17 @@ ModalWindow {
signal selected(var result); signal selected(var result);
signal canceled(); signal canceled();
property alias result: textResult.text property var items;
property alias label: mainTextContainer.text
property var result;
// FIXME not current honored
property var current;
// For text boxes
property alias placeholderText: textResult.placeholderText property alias placeholderText: textResult.placeholderText
property alias text: mainTextContainer.text
// For combo boxes
property bool editable: true;
Rectangle { Rectangle {
clip: true clip: true
@ -55,10 +63,20 @@ ModalWindow {
anchors { top: mainTextContainer.bottom; bottom: buttons.top; left: parent.left; right: parent.right; margins: d.spacing } anchors { top: mainTextContainer.bottom; bottom: buttons.top; left: parent.left; right: parent.right; margins: d.spacing }
// FIXME make a text field type that can be bound to a history for autocompletion // FIXME make a text field type that can be bound to a history for autocompletion
TextField { TextField {
focus: true
id: textResult id: textResult
focus: items ? false : true
visible: items ? false : true
anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter } anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter }
} }
VrControls.ComboBox {
id: comboBox
focus: items ? true : false
visible: items ? true : false
anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter }
model: items ? items : []
}
} }
Flow { Flow {
@ -86,6 +104,7 @@ ModalWindow {
text: qsTr("OK") text: qsTr("OK")
shortcut: Qt.Key_Return shortcut: Qt.Key_Return
onTriggered: { onTriggered: {
root.result = items ? comboBox.currentText : textResult.text
root.selected(root.result); root.selected(root.result);
root.destroy(); root.destroy();
} }

View file

@ -199,19 +199,7 @@ private slots:
} }
}; };
QMessageBox::StandardButton OffscreenUi::messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) { QQuickItem* OffscreenUi::createMessageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
if (QThread::currentThread() != thread()) {
QMessageBox::StandardButton result = QMessageBox::StandardButton::NoButton;
QMetaObject::invokeMethod(this, "messageBox", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QMessageBox::StandardButton, result),
Q_ARG(QMessageBox::Icon, icon),
Q_ARG(QString, title),
Q_ARG(QString, text),
Q_ARG(QMessageBox::StandardButtons, buttons),
Q_ARG(QMessageBox::StandardButton, defaultButton));
return result;
}
QVariantMap map; QVariantMap map;
map.insert("title", title); map.insert("title", title);
map.insert("text", text); map.insert("text", text);
@ -225,12 +213,34 @@ QMessageBox::StandardButton OffscreenUi::messageBox(QMessageBox::Icon icon, cons
if (!invokeResult) { if (!invokeResult) {
qWarning() << "Failed to create message box"; qWarning() << "Failed to create message box";
return QMessageBox::StandardButton::NoButton; return nullptr;
}
return qvariant_cast<QQuickItem*>(result);
}
QMessageBox::StandardButton OffscreenUi::waitForMessageBoxResult(QQuickItem* messageBox) {
if (!messageBox) {
return QMessageBox::NoButton;
} }
QMessageBox::StandardButton resultButton = MessageBoxListener(qvariant_cast<QQuickItem*>(result)).waitForButtonResult(); return MessageBoxListener(messageBox).waitForButtonResult();
qDebug() << "Message box got a result of " << resultButton; }
return resultButton;
QMessageBox::StandardButton OffscreenUi::messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
if (QThread::currentThread() != thread()) {
QMessageBox::StandardButton result = QMessageBox::StandardButton::NoButton;
QMetaObject::invokeMethod(this, "messageBox", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QMessageBox::StandardButton, result),
Q_ARG(QMessageBox::Icon, icon),
Q_ARG(QString, title),
Q_ARG(QString, text),
Q_ARG(QMessageBox::StandardButtons, buttons),
Q_ARG(QMessageBox::StandardButton, defaultButton));
return result;
}
return waitForMessageBoxResult(createMessageBox(icon, title, text, buttons, defaultButton));
} }
QMessageBox::StandardButton OffscreenUi::critical(const QString& title, const QString& text, QMessageBox::StandardButton OffscreenUi::critical(const QString& title, const QString& text,
@ -273,6 +283,7 @@ private slots:
// FIXME many input parameters currently ignored // FIXME many input parameters currently ignored
QString OffscreenUi::getText(void* ignored, const QString & title, const QString & label, QLineEdit::EchoMode mode, const QString & text, bool * ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints) { QString OffscreenUi::getText(void* ignored, const QString & title, const QString & label, QLineEdit::EchoMode mode, const QString & text, bool * ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints) {
if (ok) { *ok = false; }
QVariant result = DependencyManager::get<OffscreenUi>()->inputDialog(title, label, text).toString(); QVariant result = DependencyManager::get<OffscreenUi>()->inputDialog(title, label, text).toString();
if (ok && result.isValid()) { if (ok && result.isValid()) {
*ok = true; *ok = true;
@ -280,35 +291,70 @@ QString OffscreenUi::getText(void* ignored, const QString & title, const QString
return result.toString(); return result.toString();
} }
// FIXME many input parameters currently ignored
QString OffscreenUi::getItem(void *ignored, const QString & title, const QString & label, const QStringList & items, int current, bool editable, bool * ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints) {
if (ok) {
*ok = false;
}
QVariant OffscreenUi::inputDialog(const QString& query, const QString& placeholderText, const QString& currentValue) { auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto inputDialog = offscreenUi->createInputDialog(title, label, current);
if (!inputDialog) {
return QString();
}
inputDialog->setProperty("items", items);
inputDialog->setProperty("editable", editable);
QVariant result = offscreenUi->waitForInputDialogResult(inputDialog);
if (!result.isValid()) {
return QString();
}
if (ok) {
*ok = true;
}
return result.toString();
}
QVariant OffscreenUi::inputDialog(const QString& title, const QString& label, const QVariant& current) {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
QVariant result; QVariant result;
QMetaObject::invokeMethod(this, "queryBox", Qt::BlockingQueuedConnection, QMetaObject::invokeMethod(this, "inputDialog", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QVariant, result), Q_RETURN_ARG(QVariant, result),
Q_ARG(QString, query), Q_ARG(QString, title),
Q_ARG(QString, placeholderText), Q_ARG(QString, label),
Q_ARG(QString, currentValue)); Q_ARG(QVariant, current));
return result; return result;
} }
return waitForInputDialogResult(createInputDialog(title, label, current));
}
QQuickItem* OffscreenUi::createInputDialog(const QString& title, const QString& label, const QVariant& current) {
QVariantMap map; QVariantMap map;
map.insert("text", query); map.insert("title", title);
map.insert("placeholderText", placeholderText); map.insert("label", label);
map.insert("result", currentValue); map.insert("current", current);
QVariant result; QVariant result;
bool invokeResult = QMetaObject::invokeMethod(_desktop, "queryBox", bool invokeResult = QMetaObject::invokeMethod(_desktop, "inputDialog",
Q_RETURN_ARG(QVariant, result), Q_RETURN_ARG(QVariant, result),
Q_ARG(QVariant, QVariant::fromValue(map))); Q_ARG(QVariant, QVariant::fromValue(map)));
if (!invokeResult) { if (!invokeResult) {
qWarning() << "Failed to create message box"; qWarning() << "Failed to create message box";
return QVariant(); return nullptr;
} }
return InputDialogListener(qvariant_cast<QQuickItem*>(result)).waitForResult(); return qvariant_cast<QQuickItem*>(result);
} }
QVariant OffscreenUi::waitForInputDialogResult(QQuickItem* inputDialog) {
if (!inputDialog) {
return QVariant();
}
return InputDialogListener(inputDialog).waitForResult();
}
bool OffscreenUi::navigationFocused() { bool OffscreenUi::navigationFocused() {
return offscreenFlags->isNavigationFocused(); return offscreenFlags->isNavigationFocused();

View file

@ -42,6 +42,13 @@ public:
QQuickItem* getToolWindow(); QQuickItem* getToolWindow();
// Message box compatibility
Q_INVOKABLE QMessageBox::StandardButton messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
// Must be called from the main thread
QQuickItem* createMessageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
// Must be called from the main thread
QMessageBox::StandardButton waitForMessageBoxResult(QQuickItem* messageBox);
/// Same design as QMessageBox::critical(), will block, returns result /// Same design as QMessageBox::critical(), will block, returns result
static QMessageBox::StandardButton critical(void* ignored, const QString& title, const QString& text, static QMessageBox::StandardButton critical(void* ignored, const QString& title, const QString& text,
QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
@ -80,18 +87,21 @@ public:
QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
Q_INVOKABLE QMessageBox::StandardButton messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton); // file dialog compatibility
Q_INVOKABLE QVariant inputDialog(const QString& query, const QString& placeholderText = QString(), const QString& currentValue = QString());
Q_INVOKABLE QString fileOpenDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); Q_INVOKABLE QString fileOpenDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
// FIXME implement
static QVariant query(const QString& query, const QString& placeholderText = QString(), const QString& currentValue = QString());
// Compatibility with QFileDialog::getOpenFileName // Compatibility with QFileDialog::getOpenFileName
static QString getOpenFileName(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); static QString getOpenFileName(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
// input dialog compatibility
Q_INVOKABLE QVariant inputDialog(const QString& title, const QString& label = QString(), const QVariant& current = QVariant());
QQuickItem* createInputDialog(const QString& title, const QString& label, const QVariant& current);
QVariant waitForInputDialogResult(QQuickItem* inputDialog);
// Compatibility with QInputDialog::getText // Compatibility with QInputDialog::getText
static QString getText(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); static QString getText(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);
// Compatibility with QInputDialog::getItem
static QString getItem(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);
private: private:
QQuickItem* _desktop { nullptr }; QQuickItem* _desktop { nullptr };