diff --git a/CMakeLists.txt b/CMakeLists.txt index f5dc494c..94f9649f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,6 +100,17 @@ set(QML_ELEMENTS widgets/misc/CameraView widgets/misc/ErrorsWidget + widgets/config/BaseConfigDialog + widgets/config/LabeledTextField + widgets/config/LabeledCheckbox + widgets/config/LabeledSpinBox + widgets/config/LabeledDoubleSpinBox + widgets/config/LabeledComboBox + widgets/config/TitleComponent + widgets/config/ColorTable + widgets/config/ColorField + widgets/config/SectionHeader + dialogs/TopicView dialogs/TabNameDialog dialogs/TabSizeDialog @@ -113,6 +124,7 @@ set(ELEMENTS Constants SettingsManager TitleManager + Clipboard models/TabWidgetsModel models/TabListModel diff --git a/dialogs/WidgetConfig.qml b/dialogs/WidgetConfig.qml index aebce29f..5c8ce248 100644 --- a/dialogs/WidgetConfig.qml +++ b/dialogs/WidgetConfig.qml @@ -45,16 +45,12 @@ Dialog { choices = item[sub + "Choices"] typeName = "list" - } - - else if (typeName === "QVariantList") { + } else if (typeName === "QVariantList") { obj["valueType"] = item[sub + "ValueType"] obj["valueName"] = item[sub + "ValueName"] - } - - else if (typeName === "int" || typeName === "double") { - let min = item[sub + "Min"]; - let max = item[sub + "Max"]; + } else if (typeName === "int" || typeName === "double") { + let min = item[sub + "Min"] + let max = item[sub + "Max"] obj["min"] = (typeof min === "undefined") ? 0 : min obj["max"] = (typeof max === "undefined") ? 100000 : max @@ -87,13 +83,13 @@ Dialog { } function getValues() { - for (var i = 0; i < listView.count; ++i) { + for (var i = 0; i < rep.count; ++i) { let idx = lm.get(i) item[idx.name] = idx.itemValue } } - ListView { + Flow { anchors { top: parent.top bottom: parent.bottom @@ -105,412 +101,816 @@ Dialog { spacing: 8 - id: listView - - clip: true + id: flow - boundsBehavior: Flickable.StopAtBounds + Repeater { + id: rep - model: lm + clip: true - component FieldLabel: Label { - Layout.fillWidth: true + // boundsBehavior: Flickable.StopAtBounds + model: lm - text: displayText(model.name) - font.pixelSize: 15 - color: Constants.palette.text - } + component FieldLabel: Label { + Layout.fillWidth: true - delegate: DelegateChooser { - role: "type" + text: displayText(model.name) + font.pixelSize: 15 + color: Constants.palette.text + } - // TODO: may want to find a way to avoid all this repeat code - DelegateChoice { - roleValue: "QString" + delegate: DelegateChooser { + role: "type" - RowLayout { - clip: true - width: parent.width + // TODO: may want to find a way to avoid all this repeat code + DelegateChoice { + roleValue: "QString" - uniformCellSizes: true + RowLayout { + clip: true - FieldLabel {} + FieldLabel {} - TextField { - id: txt - Layout.fillWidth: true + TextField { + id: txt + Layout.fillWidth: true - font.pixelSize: 15 - text: model.itemValue + font.pixelSize: 15 + text: model.itemValue - onTextEdited: model.itemValue = text + onTextEdited: model.itemValue = text + } } } - } - DelegateChoice { - roleValue: "bool" + DelegateChoice { + roleValue: "bool" - RowLayout { - clip: true - width: parent.width - - uniformCellSizes: true + RowLayout { + clip: true - FieldLabel {} + FieldLabel {} - CheckBox { - checked: model.itemValue + CheckBox { + checked: model.itemValue - onClicked: model.itemValue = checked + onClicked: model.itemValue = checked - indicator.implicitHeight: 20 - indicator.implicitWidth: 20 + indicator.implicitHeight: 20 + indicator.implicitWidth: 20 + } } } - } - - DelegateChoice { - roleValue: "int" - RowLayout { - clip: true - width: parent.width + DelegateChoice { + roleValue: "int" - uniformCellSizes: true + RowLayout { + clip: true - FieldLabel {} + FieldLabel {} - SpinBox { - from: map.min - to: map.max + SpinBox { + from: map.min + to: map.max - id: sb + id: sb - Layout.fillWidth: true + Layout.fillWidth: true - font.pixelSize: 15 - value: model.itemValue + font.pixelSize: 15 + value: model.itemValue - onValueModified: model.itemValue = value + onValueModified: model.itemValue = value + } } } - } - - DelegateChoice { - roleValue: "double" - RowLayout { - clip: true - width: parent.width + DelegateChoice { + roleValue: "double" - uniformCellSizes: true + RowLayout { + clip: true - FieldLabel {} + FieldLabel {} - DoubleSpinBox { - from: map.min - to: map.max + DoubleSpinBox { + from: map.min + to: map.max - id: dsb - font.pixelSize: 15 - Layout.fillWidth: true + id: dsb + font.pixelSize: 15 + Layout.fillWidth: true - value: model.itemValue + value: model.itemValue - stepSize: 0.1 + stepSize: 0.1 - onValueModified: model.itemValue = value + onValueModified: model.itemValue = value + } } } - } - DelegateChoice { - roleValue: "QColor" + DelegateChoice { + roleValue: "QColor" - RowLayout { - clip: true - width: parent.width - - uniformCellSizes: true + RowLayout { + clip: true - FieldLabel {} + FieldLabel {} - TextField { - id: colorField - font.pixelSize: 15 - Layout.fillWidth: true + TextField { + id: colorField + font.pixelSize: 15 + Layout.fillWidth: true - text: model.itemValue + text: model.itemValue - onTextEdited: model.itemValue = text - } + onTextEdited: model.itemValue = text + } - Button { - Layout.fillWidth: true - text: "Pick" + Button { + Layout.fillWidth: true + text: "Pick" - function setColor() { - colorField.text = colorDialog.selectedColor - model.itemValue = colorDialog.selectedColor - colorDialog.accepted.disconnect(setColor) - } + function setColor() { + colorField.text = colorDialog.selectedColor + model.itemValue = colorDialog.selectedColor + colorDialog.accepted.disconnect(setColor) + } - onClicked: { - colorDialog.selectedColor = colorField.text - colorDialog.accepted.connect(setColor) - colorDialog.open() + onClicked: { + colorDialog.selectedColor = colorField.text + colorDialog.accepted.connect(setColor) + colorDialog.open() + } } } } - } - - DelegateChoice { - roleValue: "list" - RowLayout { - clip: true - width: parent.width + DelegateChoice { + roleValue: "list" - uniformCellSizes: true + RowLayout { + clip: true - FieldLabel {} + FieldLabel {} - function setValue(v) { - model.itemValue = v - } + function setValue(v) { + model.itemValue = v + } - ComboBox { - model: choices + ComboBox { + model: choices - delegate: ItemDelegate { - id: delegate + delegate: ItemDelegate { + id: delegate - width: choices.width - contentItem: Text { - text: modelData - color: "white" - font.pixelSize: 15 - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter + width: cb.width + contentItem: Text { + text: modelData + color: "white" + font.pixelSize: 15 + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + highlighted: choices.highlightedIndex === index } - highlighted: choices.highlightedIndex === index - } - id: cb - font.pixelSize: 15 - Layout.fillWidth: true + id: cb + font.pixelSize: 15 + Layout.fillWidth: true - Component.onCompleted: { - currentIndex = choices.indexOf(itemValue) - currentIndexChanged.connect(updateValue) - } + Component.onCompleted: { + currentIndex = choices.indexOf(itemValue) + currentIndexChanged.connect(updateValue) + } - function updateValue() { - setValue(valueAt(currentIndex)) + function updateValue() { + setValue(valueAt(currentIndex)) + } } } } - } - - DelegateChoice { - roleValue: "QVariantList" - - GridLayout { - clip: true - width: parent.width - rowSpacing: 0 + DelegateChoice { + roleValue: "QVariantList" - rows: 4 - columns: 2 + GridLayout { + clip: true + width: parent.width - FieldLabel {} + rowSpacing: 0 - function setValue(v) { - model.itemValue = v - } + rows: 4 + columns: 2 - function getValue() { - // stupid workaround because of cancer - // itemValue gets corrupted to a QQmlListModel for some reason - // kill me - return model.item[model.name] - } + FieldLabel {} - HorizontalHeaderView { - Layout.minimumWidth: parent.width - 90 - Layout.row: 0 - Layout.column: 1 + function setValue(v) { + model.itemValue = v + } - Layout.fillWidth: true + function getValue() { + // stupid workaround because of cancer + // itemValue gets corrupted to a QQmlListModel for some reason + // kill me + return model.item[model.name] + } - Layout.minimumHeight: 30 - Layout.columnSpan: 2 - id: horizontalHeader - syncView: tbl - clip: true - } + HorizontalHeaderView { + Layout.minimumWidth: parent.width - 90 + Layout.row: 0 + Layout.column: 1 - TableView { - Layout.minimumWidth: parent.width - 90 - Layout.minimumHeight: 40 - columnSpacing: 1 - rowSpacing: 1 - clip: true + Layout.fillWidth: true - id: tbl + Layout.minimumHeight: 30 + Layout.columnSpan: 2 + id: horizontalHeader + syncView: tbl + clip: true + } - Layout.fillWidth: true + TableView { + Layout.minimumWidth: parent.width - 90 + Layout.minimumHeight: 40 + columnSpacing: 1 + rowSpacing: 1 + clip: true - Layout.row: 1 - Layout.column: 1 + id: tbl - Layout.rowSpan: 3 + Layout.fillWidth: true - interactive: false + Layout.row: 1 + Layout.column: 1 - function resetHeight() { - Layout.minimumHeight = 42 * tblModel.rowCount() - } + Layout.rowSpan: 3 - Component.onCompleted: { - let vl = map.valueName - let iv = getValue() + interactive: false - for (let i = 0; i < iv.length; ++i) { - tblModel.add(iv[i]["Value"], iv[i][vl]) - tbl.resetHeight() + function resetHeight() { + Layout.minimumHeight = 42 * tblModel.rowCount() } - setValue(tblModel.asList()) - tblModel.dataChanged.connect(() => setValue(tblModel.asList())) - } + Component.onCompleted: { + let vl = map.valueName + let iv = getValue() - model: MapModel { - id: tblModel - valueName: map.valueName - } + for (var i = 0; i < iv.length; ++i) { + tblModel.add(iv[i]["Value"], iv[i][vl]) + tbl.resetHeight() + } - selectionModel: ItemSelectionModel {} - selectionBehavior: TableView.SelectRows - selectionMode: TableView.SingleSelection + setValue(tblModel.asList()) + tblModel.dataChanged.connect( + () => setValue(tblModel.asList())) + } - delegate: Rectangle { - border { - color: Constants.palette.text - width: 2 + model: MapModel { + id: tblModel + valueName: map.valueName } - required property bool selected - required property bool current + selectionModel: ItemSelectionModel {} + selectionBehavior: TableView.SelectRows + selectionMode: TableView.SingleSelection - implicitWidth: tbl.width / 2 - implicitHeight: 40 + delegate: Rectangle { + border { + color: Constants.palette.text + width: 2 + } - color: current ? "blue" : "black" + required property bool selected + required property bool current - Text { - font.pixelSize: 15 - anchors.centerIn: parent - text: display - color: Constants.palette.text - } + implicitWidth: tbl.width / 2 + implicitHeight: 40 - TableView.editDelegate: TextField { - font.pixelSize: 15 - anchors.fill: parent - text: display - horizontalAlignment: TextInput.AlignHCenter - verticalAlignment: TextInput.AlignVCenter - Component.onCompleted: selectAll() + color: current ? "blue" : "black" - TableView.onCommit: { - display = text + Text { + font.pixelSize: 15 + anchors.centerIn: parent + text: display + color: Constants.palette.text + } + + TableView.editDelegate: TextField { + font.pixelSize: 15 + anchors.fill: parent + text: display + horizontalAlignment: TextInput.AlignHCenter + verticalAlignment: TextInput.AlignVCenter + Component.onCompleted: selectAll() + + TableView.onCommit: { + display = text + } } } } - } - Button { - Layout.alignment: Qt.AlignTop | Qt.AlignLeft - Layout.row: 1 - Layout.column: 0 - text: "Add" + Button { + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + Layout.row: 1 + Layout.column: 0 + text: "Add" - onClicked: { - tblModel.add("", "") - setValue(tblModel.asList()) - tbl.resetHeight() + onClicked: { + tblModel.add("", "") + setValue(tblModel.asList()) + tbl.resetHeight() + } } - } - Button { - Layout.alignment: Qt.AlignTop | Qt.AlignLeft - Layout.row: 2 - Layout.column: 0 - text: "Delete" + Button { + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + Layout.row: 2 + Layout.column: 0 + text: "Delete" - onClicked: { - tblModel.remove(tbl.currentRow) - setValue(tblModel.asList()) - tbl.resetHeight() + onClicked: { + tblModel.remove(tbl.currentRow) + setValue(tblModel.asList()) + tbl.resetHeight() + } } } } - } - - DelegateChoice { - roleValue: "QSizeF" - RowLayout { - clip: true - width: parent.width + DelegateChoice { + roleValue: "QSizeF" + RowLayout { + clip: true - FieldLabel { - Layout.rowSpan: 4 - } + FieldLabel { + Layout.rowSpan: 4 + } - Label { - text: "Width:" - font.pixelSize: 15 - } + Label { + text: "Width:" + font.pixelSize: 15 + } - SpinBox { - from: 0 - to: 2000 + SpinBox { + from: 0 + to: 2000 - id: width + id: width - Layout.fillWidth: true + Layout.fillWidth: true - font.pixelSize: 15 - value: model.itemValue.width + font.pixelSize: 15 + value: model.itemValue.width - onValueModified: model.itemValue.width = value - } + onValueModified: model.itemValue.width = value + } - Label { - text: "Height:" - font.pixelSize: 15 - } + Label { + text: "Height:" + font.pixelSize: 15 + } - SpinBox { - from: 0 - to: 2000 + SpinBox { + from: 0 + to: 2000 - id: height + id: height - Layout.fillWidth: true + Layout.fillWidth: true - font.pixelSize: 15 - value: model.itemValue.height + font.pixelSize: 15 + value: model.itemValue.height - onValueModified: model.itemValue.height = value + onValueModified: model.itemValue.height = value + } } } } } } + + // ListView { + // anchors { + // top: parent.top + // bottom: parent.bottom + // left: parent.left + // right: parent.right + + // margins: 8 + // } + + // spacing: 8 + + // id: listView + + // clip: true + + // boundsBehavior: Flickable.StopAtBounds + + // model: lm + + // component FieldLabel: Label { + // Layout.fillWidth: true + + // text: displayText(model.name) + // font.pixelSize: 15 + // color: Constants.palette.text + // } + + // delegate: DelegateChooser { + // role: "type" + + // // TODO: may want to find a way to avoid all this repeat code + // DelegateChoice { + // roleValue: "QString" + + // RowLayout { + // clip: true + // width: parent.width + + // uniformCellSizes: true + + // FieldLabel {} + + // TextField { + // id: txt + // Layout.fillWidth: true + + // font.pixelSize: 15 + // text: model.itemValue + + // onTextEdited: model.itemValue = text + // } + // } + // } + + // DelegateChoice { + // roleValue: "bool" + + // RowLayout { + // clip: true + // width: parent.width + + // uniformCellSizes: true + + // FieldLabel {} + + // CheckBox { + // checked: model.itemValue + + // onClicked: model.itemValue = checked + + // indicator.implicitHeight: 20 + // indicator.implicitWidth: 20 + // } + // } + // } + + // DelegateChoice { + // roleValue: "int" + + // RowLayout { + // clip: true + // width: parent.width + + // uniformCellSizes: true + + // FieldLabel {} + + // SpinBox { + // from: map.min + // to: map.max + + // id: sb + + // Layout.fillWidth: true + + // font.pixelSize: 15 + // value: model.itemValue + + // onValueModified: model.itemValue = value + // } + // } + // } + + // DelegateChoice { + // roleValue: "double" + + // RowLayout { + // clip: true + // width: parent.width + + // uniformCellSizes: true + + // FieldLabel {} + + // DoubleSpinBox { + // from: map.min + // to: map.max + + // id: dsb + // font.pixelSize: 15 + // Layout.fillWidth: true + + // value: model.itemValue + + // stepSize: 0.1 + + // onValueModified: model.itemValue = value + // } + // } + // } + + // DelegateChoice { + // roleValue: "QColor" + + // RowLayout { + // clip: true + // width: parent.width + + // uniformCellSizes: true + + // FieldLabel {} + + // TextField { + // id: colorField + // font.pixelSize: 15 + // Layout.fillWidth: true + + // text: model.itemValue + + // onTextEdited: model.itemValue = text + // } + + // Button { + // Layout.fillWidth: true + // text: "Pick" + + // function setColor() { + // colorField.text = colorDialog.selectedColor + // model.itemValue = colorDialog.selectedColor + // colorDialog.accepted.disconnect(setColor) + // } + + // onClicked: { + // colorDialog.selectedColor = colorField.text + // colorDialog.accepted.connect(setColor) + // colorDialog.open() + // } + // } + // } + // } + + // DelegateChoice { + // roleValue: "list" + + // RowLayout { + // clip: true + // width: parent.width + + // uniformCellSizes: true + + // FieldLabel {} + + // function setValue(v) { + // model.itemValue = v + // } + + // ComboBox { + // model: choices + + // delegate: ItemDelegate { + // id: delegate + + // width: choices.width + // contentItem: Text { + // text: modelData + // color: "white" + // font.pixelSize: 15 + // elide: Text.ElideRight + // verticalAlignment: Text.AlignVCenter + // } + // highlighted: choices.highlightedIndex === index + // } + + // id: cb + // font.pixelSize: 15 + // Layout.fillWidth: true + + // Component.onCompleted: { + // currentIndex = choices.indexOf(itemValue) + // currentIndexChanged.connect(updateValue) + // } + + // function updateValue() { + // setValue(valueAt(currentIndex)) + // } + // } + // } + // } + + // DelegateChoice { + // roleValue: "QVariantList" + + // GridLayout { + // clip: true + // width: parent.width + + // rowSpacing: 0 + + // rows: 4 + // columns: 2 + + // FieldLabel {} + + // function setValue(v) { + // model.itemValue = v + // } + + // function getValue() { + // // stupid workaround because of cancer + // // itemValue gets corrupted to a QQmlListModel for some reason + // // kill me + // return model.item[model.name] + // } + + // HorizontalHeaderView { + // Layout.minimumWidth: parent.width - 90 + // Layout.row: 0 + // Layout.column: 1 + + // Layout.fillWidth: true + + // Layout.minimumHeight: 30 + // Layout.columnSpan: 2 + // id: horizontalHeader + // syncView: tbl + // clip: true + // } + + // TableView { + // Layout.minimumWidth: parent.width - 90 + // Layout.minimumHeight: 40 + // columnSpacing: 1 + // rowSpacing: 1 + // clip: true + + // id: tbl + + // Layout.fillWidth: true + + // Layout.row: 1 + // Layout.column: 1 + + // Layout.rowSpan: 3 + + // interactive: false + + // function resetHeight() { + // Layout.minimumHeight = 42 * tblModel.rowCount() + // } + + // Component.onCompleted: { + // let vl = map.valueName + // let iv = getValue() + + // for (let i = 0; i < iv.length; ++i) { + // tblModel.add(iv[i]["Value"], iv[i][vl]) + // tbl.resetHeight() + // } + + // setValue(tblModel.asList()) + // tblModel.dataChanged.connect(() => setValue(tblModel.asList())) + // } + + // model: MapModel { + // id: tblModel + // valueName: map.valueName + // } + + // selectionModel: ItemSelectionModel {} + // selectionBehavior: TableView.SelectRows + // selectionMode: TableView.SingleSelection + + // delegate: Rectangle { + // border { + // color: Constants.palette.text + // width: 2 + // } + + // required property bool selected + // required property bool current + + // implicitWidth: tbl.width / 2 + // implicitHeight: 40 + + // color: current ? "blue" : "black" + + // Text { + // font.pixelSize: 15 + // anchors.centerIn: parent + // text: display + // color: Constants.palette.text + // } + + // TableView.editDelegate: TextField { + // font.pixelSize: 15 + // anchors.fill: parent + // text: display + // horizontalAlignment: TextInput.AlignHCenter + // verticalAlignment: TextInput.AlignVCenter + // Component.onCompleted: selectAll() + + // TableView.onCommit: { + // display = text + // } + // } + // } + // } + + // Button { + // Layout.alignment: Qt.AlignTop | Qt.AlignLeft + // Layout.row: 1 + // Layout.column: 0 + // text: "Add" + + // onClicked: { + // tblModel.add("", "") + // setValue(tblModel.asList()) + // tbl.resetHeight() + // } + // } + + // Button { + // Layout.alignment: Qt.AlignTop | Qt.AlignLeft + // Layout.row: 2 + // Layout.column: 0 + // text: "Delete" + + // onClicked: { + // tblModel.remove(tbl.currentRow) + // setValue(tblModel.asList()) + // tbl.resetHeight() + // } + // } + // } + // } + + // DelegateChoice { + // roleValue: "QSizeF" + + // RowLayout { + // clip: true + // width: parent.width + + // FieldLabel { + // Layout.rowSpan: 4 + // } + + // Label { + // text: "Width:" + // font.pixelSize: 15 + // } + + // SpinBox { + // from: 0 + // to: 2000 + + // id: width + + // Layout.fillWidth: true + + // font.pixelSize: 15 + // value: model.itemValue.width + + // onValueModified: model.itemValue.width = value + // } + + // Label { + // text: "Height:" + // font.pixelSize: 15 + // } + + // SpinBox { + // from: 0 + // to: 2000 + + // id: height + + // Layout.fillWidth: true + + // font.pixelSize: 15 + // value: model.itemValue.height + + // onValueModified: model.itemValue.height = value + // } + // } + // } + // } + // } } diff --git a/include/Clipboard.h b/include/Clipboard.h new file mode 100644 index 00000000..871b6a45 --- /dev/null +++ b/include/Clipboard.h @@ -0,0 +1,20 @@ +#ifndef CLIPBOARD_H +#define CLIPBOARD_H + +#include +#include + +class Clipboard : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON +public: + Clipboard(QObject *parent = nullptr); + + Q_INVOKABLE void copy(const QString &text); + +signals: +}; + +#endif // CLIPBOARD_H diff --git a/include/models/MapModel.h b/include/models/MapModel.h index 7ee564b3..8b024ef3 100644 --- a/include/models/MapModel.h +++ b/include/models/MapModel.h @@ -39,6 +39,7 @@ class MapModel : public QAbstractTableModel Q_INVOKABLE void add(QString key = "", QString value = ""); Q_INVOKABLE void remove(int row); Q_INVOKABLE QVariantList asList(); + Q_INVOKABLE void toList(const QVariantList &list); QString valueName() const; void setValueName(const QString &newValueName); diff --git a/main.cpp b/main.cpp index 12d3fb7e..e30f9fb5 100644 --- a/main.cpp +++ b/main.cpp @@ -5,6 +5,7 @@ #include "AccentsListModel.h" #include "BuildConfig.h" +#include "Clipboard.h" #include "Flags.h" #include "Globals.h" #include "TitleManager.h" @@ -34,6 +35,8 @@ int main(int argc, char *argv[]) AccentsListModel *accents = new AccentsListModel(&app); accents->load(); + Clipboard *clipboard = new Clipboard(&app); + Globals::inst.AddConnectionListener(true, [topics, &store, title] (const nt::Event &event) { bool connected = event.Is(nt::EventFlags::kConnected); @@ -91,6 +94,7 @@ int main(int argc, char *argv[]) engine.rootContext()->setContextProperty("tlm", tlm); engine.rootContext()->setContextProperty("titleManager", title); engine.rootContext()->setContextProperty("accents", accents); + engine.rootContext()->setContextProperty("clipboard", clipboard); QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, diff --git a/src/Clipboard.cpp b/src/Clipboard.cpp new file mode 100644 index 00000000..002e71cb --- /dev/null +++ b/src/Clipboard.cpp @@ -0,0 +1,12 @@ +#include "Clipboard.h" +#include +#include + +Clipboard::Clipboard(QObject *parent) + : QObject{parent} +{} + +void Clipboard::copy(const QString &text) +{ + qApp->clipboard()->setText(text); +} diff --git a/src/models/MapModel.cpp b/src/models/MapModel.cpp index c502eb84..916b5122 100644 --- a/src/models/MapModel.cpp +++ b/src/models/MapModel.cpp @@ -124,6 +124,18 @@ QVariantList MapModel::asList() } +void MapModel::toList(const QVariantList &list) +{ + beginResetModel(); + m_data.clear(); + endResetModel(); + + for (const QVariant &v : list) { + QVariantMap m = v.toMap(); + add(m.value("Value").toString(), m.value(m_valueName).toString()); + } +} + QString MapModel::valueName() const { return m_valueName; diff --git a/widgets/BaseWidget.qml b/widgets/BaseWidget.qml index 10e35bb3..c32b70d1 100644 --- a/widgets/BaseWidget.qml +++ b/widgets/BaseWidget.qml @@ -106,7 +106,8 @@ Rectangle { MenuItem { text: "Configure" - onTriggered: openConf(rcMenu.parent) + // onTriggered: openConf(rcMenu.parent) + onTriggered: config.openDialog() } MenuItem { @@ -301,4 +302,76 @@ Rectangle { horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } + + /** + * This is the "base" configuration dialog containing the NT and font settings. + * Copy it for your widget. + */ + BaseConfigDialog { + // id: config + + height: 450 + + function openDialog() { + topicField.open() + titleFontField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: parent.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + LabeledSpinBox { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: rect + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: rect + } + } + } } diff --git a/widgets/config/BaseConfigDialog.qml b/widgets/config/BaseConfigDialog.qml new file mode 100644 index 00000000..5dce1ce1 --- /dev/null +++ b/widgets/config/BaseConfigDialog.qml @@ -0,0 +1,30 @@ +import QtQuick +import QtQuick.Controls + +import QFRCDashboard + +Dialog { + id: config + + property int headerHeight: 40 + + width: 375 + spacing: 10 + + standardButtons: Dialog.Ok | Dialog.Cancel + + TitleComponent {} + + background: Rectangle { + color: "transparent" + } + + contentItem: Rectangle { + color: Constants.palette.dialogBg + radius: 20 + anchors.fill: parent + } + + parent: Overlay.overlay + anchors.centerIn: parent +} diff --git a/widgets/config/ColorField.qml b/widgets/config/ColorField.qml new file mode 100644 index 00000000..18b02d49 --- /dev/null +++ b/widgets/config/ColorField.qml @@ -0,0 +1,50 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts +import QtQuick.Shapes 2.15 +import QtQuick.Dialogs + +import QFRCDashboard + +RowLayout { + required property string label + + /** what property to bind to */ + required property string bindedProperty + + /** the target to bind the property to */ + required property var bindTarget + + function open() { + textField.open() + } + + function accept() { + textField.accept() + } + + ColorDialog { + id: colorDialog + + selectedColor: textField.text + onAccepted: textField.text = colorDialog.selectedColor + } + + LabeledTextField { + id: textField + Layout.fillWidth: true + + label: parent.label + bindedProperty: parent.bindedProperty + bindTarget: parent.bindTarget + } + + Button { + Layout.fillWidth: true + text: "Pick" + + onClicked: { + colorDialog.open() + } + } +} diff --git a/widgets/config/ColorTable.qml b/widgets/config/ColorTable.qml new file mode 100644 index 00000000..afddc68b --- /dev/null +++ b/widgets/config/ColorTable.qml @@ -0,0 +1,155 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Dialogs +import QtQuick.Shapes 2.15 + +import QFRCDashboard + +ColumnLayout { + required property string label + + /** what property to bind to */ + required property string bindedProperty + + /** the target to bind the property to */ + required property var bindTarget + + + function open() { + tblModel.toList(bindTarget[bindedProperty]) + tbl.resetHeight() + } + + function accept() { + bindTarget[bindedProperty] = tblModel.asList() + } + + id: col + + spacing: 0 + + ColorDialog { + id: colorDialog + + onAccepted: Clipboard.copy(selectedColor) + } + + Text { + id: floatingLabel + text: label + color: Constants.palette.text + + font.pixelSize: 15 + } + + HorizontalHeaderView { + Layout.minimumWidth: parent.width - 90 + Layout.row: 0 + Layout.column: 1 + + Layout.fillWidth: true + + Layout.minimumHeight: 30 + Layout.columnSpan: 2 + id: horizontalHeader + syncView: tbl + clip: true + } + + TableView { + Layout.minimumWidth: parent.width - 90 + Layout.minimumHeight: 40 + columnSpacing: 1 + rowSpacing: 1 + clip: true + + id: tbl + + Layout.fillWidth: true + + Layout.row: 1 + Layout.column: 1 + + Layout.rowSpan: 3 + + interactive: false + + function resetHeight() { + Layout.minimumHeight = 42 * tblModel.rowCount() + } + + model: MapModel { + id: tblModel + valueName: "Color" + } + + selectionModel: ItemSelectionModel {} + selectionBehavior: TableView.SelectRows + selectionMode: TableView.SingleSelection + + delegate: Rectangle { + border { + color: Constants.palette.text + width: 2 + } + + required property bool selected + required property bool current + + implicitWidth: tbl.width / 2 + implicitHeight: 40 + + color: current ? "blue" : "black" + + Text { + font.pixelSize: 15 + anchors.centerIn: parent + text: display + color: Constants.palette.text + } + + TableView.editDelegate: TextField { + font.pixelSize: 15 + anchors.fill: parent + text: display + horizontalAlignment: TextInput.AlignHCenter + verticalAlignment: TextInput.AlignVCenter + Component.onCompleted: selectAll() + + TableView.onCommit: { + display = text + } + } + } + } + + RowLayout { + Button { + Layout.alignment: Qt.AlignLeft + text: "Add" + + onClicked: { + tblModel.add("", "") + tbl.resetHeight() + } + } + + Button { + Layout.alignment: Qt.AlignLeft + text: "Delete" + + onClicked: { + tblModel.remove(tbl.currentRow) + tbl.resetHeight() + } + } + + Button { + Layout.alignment: Qt.AlignLeft + text: "Copy Color" + + onClicked: colorDialog.open() + } + } +} diff --git a/widgets/config/LabeledCheckbox.qml b/widgets/config/LabeledCheckbox.qml new file mode 100644 index 00000000..8b4087f4 --- /dev/null +++ b/widgets/config/LabeledCheckbox.qml @@ -0,0 +1,30 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 2.15 + +import QtMultimedia + +import QFRCDashboard + +CheckBox { + required property string label + + /** what property to bind to */ + required property string bindedProperty + + /** the target to bind the property to */ + required property var bindTarget + + id: textField + font.pixelSize: 18 + + function open() { + checked = bindTarget[bindedProperty] + } + + function accept() { + bindTarget[bindedProperty] = checked + } + + text: label +} diff --git a/widgets/config/LabeledComboBox.qml b/widgets/config/LabeledComboBox.qml new file mode 100644 index 00000000..cd719e47 --- /dev/null +++ b/widgets/config/LabeledComboBox.qml @@ -0,0 +1,61 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Shapes 2.15 + +import QFRCDashboard + +ComboBox { + required property string label + + /** what property to bind to */ + required property string bindedProperty + + /** the target to bind the property to */ + required property var bindTarget + + /** choices for the combobox */ + required property var choices + + id: combo + model: choices + font.pixelSize: 15 + + function open() { + currentIndex = indexOfValue(bindTarget[bindedProperty]) + } + + function accept() { + bindTarget[bindedProperty] = currentText + } + + delegate: ItemDelegate { + id: delegate + + width: combo.width + contentItem: Text { + text: modelData + color: "white" + font.pixelSize: 15 + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + highlighted: combo.highlightedIndex === index + } + + Text { + id: floatingLabel + text: label + color: Constants.palette.text + + font.pixelSize: 15 + + anchors { + left: parent.left + bottom: parent.top + + bottomMargin: -2 + leftMargin: 10 + } + } +} diff --git a/widgets/config/LabeledDoubleSpinBox.qml b/widgets/config/LabeledDoubleSpinBox.qml new file mode 100644 index 00000000..e7a6f3f7 --- /dev/null +++ b/widgets/config/LabeledDoubleSpinBox.qml @@ -0,0 +1,115 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 2.15 + +import QtMultimedia + +import QFRCDashboard + +DoubleSpinBox { + id: spin + required property string label + + /** what property to bind to */ + required property string bindedProperty + + /** the target to bind the property to */ + required property var bindTarget + + from: -1E9 + to: 1E9 + + font.pixelSize: 18 + + function open() { + value = bindTarget[bindedProperty] + } + + function accept() { + bindTarget[bindedProperty] = value + } + + contentItem: SpinBox { + width: spin.availableWidth + height: spin.availableHeight + editable: spin.editable + inputMethodHints: spin.inputMethodHints + validator: spin.validator + from: -0x7FFFFFFF; to: 0x7FFFFFFF; + + contentItem: TextInput { + text: parent.textFromValue(parent.value, parent.locale) + + font: parent.font + color: Constants.palette.text + // selectionColor: "#21be2b" + // selectedTextColor: "#ffffff" + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + inputMethodHints: Qt.ImhFormattedNumbersOnly + } + + up.indicator: Rectangle { + x: spin.mirrored ? 0 : parent.width - width + height: parent.height + implicitWidth: 40 + implicitHeight: 40 + color: Constants.palette.bg + border.color: Constants.palette.text + + Text { + text: "+" + font.pixelSize: spin.font.pixelSize * 2 + color: Constants.palette.text + anchors.fill: parent + fontSizeMode: Text.Fit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + down.indicator: Rectangle { + x: spin.mirrored ? parent.width - width : 0 + height: parent.height + implicitWidth: 40 + implicitHeight: 40 + color: Constants.palette.bg + border.color: Constants.palette.text + + Text { + text: "-" + font.pixelSize: spin.font.pixelSize * 2 + color: Constants.palette.text + anchors.fill: parent + fontSizeMode: Text.Fit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + background: Rectangle { + color: Constants.palette.bg + width: parent.width + border.color: Constants.palette.text + border.width: 2 + radius: 5 + } + } + + Text { + id: floatingLabel + text: label + color: Constants.palette.text + + font.pixelSize: 15 + + anchors { + left: spin.left + bottom: spin.top + + bottomMargin: -2 + leftMargin: 10 + } + } +} diff --git a/widgets/config/LabeledSpinBox.qml b/widgets/config/LabeledSpinBox.qml new file mode 100644 index 00000000..68f67a16 --- /dev/null +++ b/widgets/config/LabeledSpinBox.qml @@ -0,0 +1,106 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 2.15 + +import QtMultimedia + +import QFRCDashboard + +SpinBox { + id: spin + required property string label + + /** what property to bind to */ + required property string bindedProperty + + /** the target to bind the property to */ + required property var bindTarget + + font.pixelSize: 18 + + from: 0 + to: 1E9 + + contentItem: TextInput { + text: parent.textFromValue(parent.value, parent.locale) + + font: parent.font + color: Constants.palette.text + // selectionColor: "#21be2b" + // selectedTextColor: "#ffffff" + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + inputMethodHints: Qt.ImhFormattedNumbersOnly + } + + function open() { + value = bindTarget[bindedProperty] + } + + function accept() { + bindTarget[bindedProperty] = value + } + + up.indicator: Rectangle { + x: spin.mirrored ? 0 : parent.width - width + height: parent.height + implicitWidth: 40 + implicitHeight: 40 + color: Constants.palette.bg + border.color: Constants.palette.text + + Text { + text: "+" + font.pixelSize: spin.font.pixelSize * 2 + color: Constants.palette.text + anchors.fill: parent + fontSizeMode: Text.Fit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + down.indicator: Rectangle { + x: spin.mirrored ? parent.width - width : 0 + height: parent.height + implicitWidth: 40 + implicitHeight: 40 + color: Constants.palette.bg + border.color: Constants.palette.text + + Text { + text: "-" + font.pixelSize: spin.font.pixelSize * 2 + color: Constants.palette.text + anchors.fill: parent + fontSizeMode: Text.Fit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + background: Rectangle { + color: Constants.palette.bg + width: parent.width + border.color: Constants.palette.text + border.width: 2 + radius: 5 + } + + Text { + id: floatingLabel + text: label + color: Constants.palette.text + + font.pixelSize: 15 + + anchors { + left: spin.left + bottom: spin.top + + bottomMargin: -2 + leftMargin: 10 + } + } +} diff --git a/widgets/config/LabeledTextField.qml b/widgets/config/LabeledTextField.qml new file mode 100644 index 00000000..1726bc5d --- /dev/null +++ b/widgets/config/LabeledTextField.qml @@ -0,0 +1,54 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 2.15 + +import QtMultimedia + +import QFRCDashboard + +TextField { + required property string label + + /** what property to bind to */ + required property string bindedProperty + + /** the target to bind the property to */ + required property var bindTarget + + id: textField + font.pixelSize: 18 + + color: Constants.palette.text + + function open() { + text = bindTarget[bindedProperty] + } + + function accept() { + bindTarget[bindedProperty] = text + } + + background: Rectangle { + color: Constants.palette.bg + width: parent.width + border.color: Constants.palette.text + border.width: 2 + radius: 5 + } + + Text { + id: floatingLabel + text: label + color: Constants.palette.text + + font.pixelSize: 15 + + anchors { + left: textField.left + bottom: textField.top + + bottomMargin: -2 + leftMargin: 10 + } + } +} diff --git a/widgets/config/SectionHeader.qml b/widgets/config/SectionHeader.qml new file mode 100644 index 00000000..5affe6ce --- /dev/null +++ b/widgets/config/SectionHeader.qml @@ -0,0 +1,28 @@ +import QtQuick + +import QFRCDashboard + +Text { + width: parent.width + + /** What text to display */ + required property string label + + font.pixelSize: 18 + font.bold: true + color: Constants.palette.text + text: label + + Rectangle { + height: 2 + width: 350 + color: Constants.palette.text + + anchors { + top: parent.bottom + left: parent.left + + margins: 2 + } + } +} diff --git a/widgets/config/TitleComponent.qml b/widgets/config/TitleComponent.qml new file mode 100644 index 00000000..da710a39 --- /dev/null +++ b/widgets/config/TitleComponent.qml @@ -0,0 +1,31 @@ +import QtQuick +import QtQuick.Controls + +import QFRCDashboard + +Rectangle { + color: Constants.accent + topLeftRadius: 20 + topRightRadius: 20 + + height: 40 + width: parent.width + + Text { + id: txt + + text: "Configure Widget" + font.pixelSize: 24 + font.bold: true + + color: "white" + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + anchors { + fill: parent + margins: 8 + } + } +} diff --git a/widgets/misc/CameraView.qml b/widgets/misc/CameraView.qml index ffb39307..09809112 100644 --- a/widgets/misc/CameraView.qml +++ b/widgets/misc/CameraView.qml @@ -1,11 +1,13 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts 6.6 import QtMultimedia import QFRCDashboard BaseWidget { + id: widget property string item_topic property var item_url: "" @@ -17,12 +19,14 @@ BaseWidget { property int item_fps: 0 property int fpsMax: 240 - property size item_resolution: Qt.size(0, 0) + property int item_resW: 0 + property int item_resH: 0 onItem_urlChanged: player.resetSource() onItem_fpsChanged: player.resetSource() onItem_qualityChanged: player.resetSource() - onItem_resolutionChanged: player.resetSource() + onItem_resWChanged: player.resetSource() + onItem_resHChanged: player.resetSource() MenuItem { id: reconnItem @@ -33,9 +37,17 @@ BaseWidget { } function fixUrls(value) { - for (let i = 0; i < value.length; ++i) { - if (value[i].startsWith("mjpg:")) value[i] = value[i].substring(5) + for (var i = 0; i < value.length; ++i) { + if (value[i].startsWith("mjpg:")) + value[i] = value[i].substring(5) + + if (value[i].includes("local")) { + value.splice(i, 1) + --i + } } + + console.log(value) } function updateTopic(ntTopic, ntValue) { @@ -43,7 +55,10 @@ BaseWidget { urlChoices = ntValue fixUrls(urlChoices) - if (urlChoices.length > 0 && item_url === "") item_url = urlChoices[0] + if (urlChoices.length > 0 && item_url === "") + item_url = urlChoices[0] + + player.resetSource() } } @@ -87,7 +102,12 @@ BaseWidget { } function resetSource() { - source = Qt.url(item_url + (item_quality !== 0 ? "compression=" + item_quality + "&" : "") + (item_fps !== 0 ? "fps=" + item_fps + "&" : "") + (item_resolution !== Qt.size(0, 0) ? "resolution=" + item_resolution.width + "x" + item_resolution.height : "")) + source = Qt.url(item_url + (item_quality !== 0 ? "compression=" + + item_quality + "&" : "") + + (item_fps !== 0 ? "fps=" + item_fps + "&" : "") + + (item_resH !== Qt.size( + 0, 0) ? "resolution=" + item_resW + "x" + + item_resH : "")) } function reconnect() { @@ -118,6 +138,164 @@ BaseWidget { topicStore.subscribe(item_topic + "/streams") model.topic = item_topic - updateTopic(item_topic + "/streams", topicStore.getValue(model.topic + "/streams")) + updateTopic(item_topic + "/streams", + topicStore.getValue(model.topic + "/streams")) + } + + BaseConfigDialog { + id: config + + height: 450 + + function openDialog() { + topicField.open() + titleFontField.open() + fpsField.open() + resHField.open() + resWField.open() + qualityField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fpsField.accept() + resHField.accept() + resWField.accept() + qualityField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + LabeledSpinBox { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + SectionHeader { + label: "Stream Settings" + } + + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + // Layout.preferredWidth: 300 + + LabeledSpinBox { + Layout.fillWidth: true + + id: fpsField + + label: "FPS" + + bindedProperty: "item_fps" + bindTarget: widget + } + + Text { + font.pixelSize: 16 + text: "Resolution" + color: Constants.palette.text + } + + LabeledSpinBox { + Layout.fillWidth: true + id: resWField + + label: "Width" + + bindedProperty: "item_resW" + bindTarget: widget + } + + Text { + font.pixelSize: 18 + text: "x" + color: Constants.palette.text + } + + LabeledSpinBox { + Layout.fillWidth: true + id: resHField + + label: "Height" + + bindedProperty: "item_resH" + bindTarget: widget + } + } + + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + Text { + font.pixelSize: 16 + text: "Quality" + color: Constants.palette.text + } + + Slider { + Layout.fillWidth: true + id: qualityField + + from: 0 + to: 100 + stepSize: 10 + + function open() { + value = widget.item_quality + } + + function accept() { + widget.item_quality = value + } + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } } } diff --git a/widgets/misc/ErrorsWidget.qml b/widgets/misc/ErrorsWidget.qml index b0ea1165..879ff48b 100644 --- a/widgets/misc/ErrorsWidget.qml +++ b/widgets/misc/ErrorsWidget.qml @@ -1,9 +1,11 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget property string item_topic property int item_fontSize: 15 @@ -70,5 +72,89 @@ BaseWidget { errors = topicStore.getValue(topic) listView.model = errors.length / 2 } + + BaseConfigDialog { + id: config + + height: 300 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/primitive/BoolWidget.qml b/widgets/primitive/BoolWidget.qml index fa351dbe..c3bb46e3 100644 --- a/widgets/primitive/BoolWidget.qml +++ b/widgets/primitive/BoolWidget.qml @@ -1,18 +1,16 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget + property string item_topic property int item_checkboxSize: 20 - property list item_test: [] - - property string testValueType: "color" - property string testValueName: "Color" - Menu { id: switchMenu title: "Switch Widget..." @@ -70,4 +68,88 @@ BaseWidget { control.checked = topicStore.getValue(item_topic) } + + BaseConfigDialog { + id: config + + height: 300 + + function openDialog() { + topicField.open() + titleFontField.open() + checkboxField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + checkboxField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: checkboxField + + label: "Checkbox Size" + + bindedProperty: "item_checkboxSize" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/primitive/ColorWidget.qml b/widgets/primitive/ColorWidget.qml index 3a03ba09..ac1e789f 100644 --- a/widgets/primitive/ColorWidget.qml +++ b/widgets/primitive/ColorWidget.qml @@ -1,10 +1,12 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts import QtQuick.Shapes 2.15 import QFRCDashboard BaseWidget { + id: widget property string item_topic property color item_falseColor: "#FF0000" @@ -81,4 +83,120 @@ BaseWidget { model.topic = item_topic updateTopic(model.topic, topicStore.getValue(model.topic)) } + + BaseConfigDialog { + id: config + + height: 475 + + function openDialog() { + topicField.open() + titleFontField.open() + shapeField.open() + trueField.open() + falseField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + shapeField.accept() + trueField.accept() + falseField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: 50 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + LabeledSpinBox { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + SectionHeader { + label: "Color Settings" + } + + LabeledComboBox { + id: shapeField + + Layout.fillWidth: true + choices: shapeChoices + + label: "Shape" + + bindedProperty: "item_shape" + bindTarget: widget + } + + RowLayout { + Layout.fillWidth: true + + ColorField { + id: trueField + + Layout.fillWidth: true + + label: "True Color" + + bindedProperty: "item_trueColor" + bindTarget: widget + } + + ColorField { + id: falseField + + Layout.fillWidth: true + + label: "False Color" + + bindedProperty: "item_falseColor" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/primitive/DoubleDialWidget.qml b/widgets/primitive/DoubleDialWidget.qml index 4ad764c5..2f0c1d66 100644 --- a/widgets/primitive/DoubleDialWidget.qml +++ b/widgets/primitive/DoubleDialWidget.qml @@ -1,19 +1,21 @@ import QtQuick import QtQuick.Controls 6.6 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget property string item_topic property int item_fontSize: 15 property double item_stepSize: 0.1 - property double item_startAngle: 180 - property double item_endAngle: 540 + property double item_startAngle: -180 + property double item_endAngle: 180 property double item_lowerBound: 0 - property double item_upperBound: 1000.0 + property double item_upperBound: 100000.0 Menu { id: switchMenu @@ -159,4 +161,173 @@ BaseWidget { spin.value = topicStore.getValue(item_topic) dial.value = topicStore.getValue(item_topic) } + + BaseConfigDialog { + id: config + + height: 600 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + upField.open() + lowField.open() + stepField.open() + startField.open() + endField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + upField.accept() + lowField.accept() + stepField.accept() + startField.accept() + endField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "Spin Box Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: lowField + + label: "Lower Bound" + + bindedProperty: "item_lowerBound" + bindTarget: widget + } + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: upField + + label: "Upper Bound" + + bindedProperty: "item_upperBound" + bindTarget: widget + } + } + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: stepField + + label: "Step Size" + + bindedProperty: "item_stepSize" + bindTarget: widget + + from: 0 + stepSize: 0.1 + } + + SectionHeader { + label: "Dial Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: startField + + label: "Start Angle" + + bindedProperty: "item_startAngle" + bindTarget: widget + } + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: endField + + label: "End Angle" + + bindedProperty: "item_endAngle" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/primitive/DoubleWidget.qml b/widgets/primitive/DoubleWidget.qml index 625a1260..897feef7 100644 --- a/widgets/primitive/DoubleWidget.qml +++ b/widgets/primitive/DoubleWidget.qml @@ -1,16 +1,19 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget + property string item_topic property int item_fontSize: 15 - property double item_stepSize: 0.1 + property double item_stepSize: 0.1 property double item_lowerBound: 0 - property double item_upperBound: 1000.0 + property double item_upperBound: 100000.0 Menu { id: switchMenu @@ -78,4 +81,139 @@ BaseWidget { model.topic = item_topic spin.value = topicStore.getValue(item_topic) } + + BaseConfigDialog { + id: config + + height: 500 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + upField.open() + lowField.open() + stepField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + upField.accept() + lowField.accept() + stepField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "Spin Box Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: lowField + + label: "Lower Bound" + + bindedProperty: "item_lowerBound" + bindTarget: widget + } + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: upField + + label: "Upper Bound" + + bindedProperty: "item_upperBound" + bindTarget: widget + } + } + + LabeledDoubleSpinBox { + Layout.fillWidth: true + + id: stepField + + label: "Step Size" + + bindedProperty: "item_stepSize" + bindTarget: widget + + from: 0 + stepSize: 0.1 + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/primitive/EnumWidget.qml b/widgets/primitive/EnumWidget.qml index a8e60f60..0ed44299 100644 --- a/widgets/primitive/EnumWidget.qml +++ b/widgets/primitive/EnumWidget.qml @@ -1,10 +1,12 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts import QtQuick.Shapes 2.15 import QFRCDashboard BaseWidget { + id: widget property string item_topic // @disable-check M311 @@ -16,9 +18,6 @@ BaseWidget { property list item_colorMap: [] - property string colorMapValueType: "color" - property string colorMapValueName: "Color" - Menu { id: switchMenu title: "Switch Widget..." @@ -36,7 +35,7 @@ BaseWidget { let obj = item_colorMap[i]; if (obj["Value"] === value) { - return obj[colorMapValueName] + return obj["Color"] } } @@ -95,4 +94,110 @@ BaseWidget { updateTopic(model.topic, topicStore.getValue(model.topic)) } + + BaseConfigDialog { + id: config + + height: 450 + + function openDialog() { + topicField.open() + titleFontField.open() + colorTable.open() + shapeField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + colorTable.accept() + shapeField.accept() + } + + ScrollView { + clip: true + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: 50 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + ColumnLayout { + id: layout + spacing: 25 + anchors.fill: parent + clip: true + + SectionHeader { + label: "Font Settings" + } + + LabeledSpinBox { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + SectionHeader { + label: "Color Settings" + } + + ColorTable { + id: colorTable + + Layout.fillWidth: true + clip: true + + label: "Color Map" + + bindedProperty: "item_colorMap" + bindTarget: widget + } + + LabeledComboBox { + id: shapeField + + Layout.fillWidth: true + choices: shapeChoices + + label: "Shape" + + bindedProperty: "item_shape" + bindTarget: widget + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } + } } diff --git a/widgets/primitive/IntWidget.qml b/widgets/primitive/IntWidget.qml index 60dc6016..bde29243 100644 --- a/widgets/primitive/IntWidget.qml +++ b/widgets/primitive/IntWidget.qml @@ -1,14 +1,20 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget + property string item_topic property int item_fontSize: 15 property int item_stepSize: 1 + property int item_upperBound: 100000 + property int item_lowerBound: 0 + Menu { id: switchMenu title: "Switch Widget..." @@ -38,6 +44,8 @@ BaseWidget { value: 0 stepSize: item_stepSize + from: item_lowerBound + to: item_upperBound anchors { verticalCenter: parent.verticalCenter @@ -71,4 +79,138 @@ BaseWidget { model.topic = item_topic spin.value = topicStore.getValue(item_topic) } + + BaseConfigDialog { + id: config + + height: 500 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + upField.open() + lowField.open() + stepField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + upField.accept() + lowField.accept() + stepField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "Spin Box Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: lowField + + label: "Lower Bound" + + bindedProperty: "item_lowerBound" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: upField + + label: "Upper Bound" + + bindedProperty: "item_upperBound" + bindTarget: widget + } + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: stepField + + label: "Step Size" + + bindedProperty: "item_stepSize" + bindTarget: widget + + from: 0 + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/primitive/TextWidget.qml b/widgets/primitive/TextWidget.qml index ee7d4668..5772c2d0 100644 --- a/widgets/primitive/TextWidget.qml +++ b/widgets/primitive/TextWidget.qml @@ -1,9 +1,11 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget property string item_topic property int item_fontSize: 15 @@ -67,4 +69,88 @@ BaseWidget { model.topic = item_topic textField.text = topicStore.getValue(item_topic) } + + BaseConfigDialog { + id: config + + height: 300 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/sendable/Command.qml b/widgets/sendable/Command.qml index ba64eca4..a54d83f3 100644 --- a/widgets/sendable/Command.qml +++ b/widgets/sendable/Command.qml @@ -1,10 +1,12 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 -import QtQuick.Layouts 2.15 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget + property string item_topic property int item_fontSize: 18 @@ -67,4 +69,88 @@ BaseWidget { cmdButton.update() } + + BaseConfigDialog { + id: config + + height: 300 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/sendable/FMSInfo.qml b/widgets/sendable/FMSInfo.qml index 55c933e6..2f741780 100644 --- a/widgets/sendable/FMSInfo.qml +++ b/widgets/sendable/FMSInfo.qml @@ -1,11 +1,12 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 -import QtQuick.Layouts 2.15 +import QtQuick.Layouts import QFDFlags import QFRCDashboard BaseWidget { + id: widget property string item_topic property int item_fontSize: 18 @@ -282,4 +283,88 @@ BaseWidget { stateText.update() gsm.update() } + + BaseConfigDialog { + id: config + + height: 300 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } } diff --git a/widgets/sendable/Field2d.qml b/widgets/sendable/Field2d.qml index aeb99c2d..cb813896 100644 --- a/widgets/sendable/Field2d.qml +++ b/widgets/sendable/Field2d.qml @@ -1,11 +1,13 @@ import QtQuick 6.2 import QtQuick.Controls 2.15 -import QtQuick.Layouts 2.15 +import QtQuick.Layouts 6.6 import QtQuick.Shapes 2.15 import QFRCDashboard BaseWidget { + id: widget + property string item_topic property bool item_useVerticalField: false @@ -120,7 +122,7 @@ BaseWidget { let realFieldY = field.y + (field.height - field.paintedHeight) / 2 let startPoint = item_useVerticalField ? Qt.point(realFieldX + field.paintedWidth - width, realFieldY + field.paintedHeight) - : Qt.point(realFieldX, realFieldY + field.paintedHeight) + : Qt.point(realFieldX, realFieldY + field.paintedHeight) x = startPoint.x + xPixels y = startPoint.y - yPixels - height @@ -199,4 +201,199 @@ BaseWidget { robot.update() } + + BaseConfigDialog { + id: config + + height: 550 + width: 450 + + function openDialog() { + topicField.open() + titleFontField.open() + robotShapeField.open() + colorField.open() + robotWField.open() + robotLField.open() + vertField.open() + mirrorRedField.open() + fieldField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + robotShapeField.accept() + colorField.accept() + robotWField.accept() + robotLField.accept() + vertField.accept() + mirrorRedField.accept() + fieldField.accept() + } + + ScrollView { + clip: true + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: 50 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + ColumnLayout { + id: layout + spacing: 25 + anchors.fill: parent + clip: true + + SectionHeader { + label: "Font Settings" + } + + LabeledSpinBox { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + SectionHeader { + label: "Robot Settings" + } + + RowLayout { + Layout.fillWidth: true + uniformCellSizes: true + + LabeledComboBox { + id: robotShapeField + + Layout.fillWidth: true + + label: "Robot Shape" + + bindedProperty: "item_robotShape" + bindTarget: widget + + choices: robotShapeChoices + } + + ColorField { + id: colorField + + Layout.fillWidth: true + + label: "Robot Color" + + bindedProperty: "item_robotColor" + bindTarget: widget + } + } + + RowLayout { + Layout.fillWidth: true + uniformCellSizes: true + + LabeledDoubleSpinBox { + id: robotWField + + Layout.fillWidth: true + from: 0 + + label: "Robot Width (m)" + + bindedProperty: "item_robotWidthMeters" + bindTarget: widget + + stepSize: 0.1 + } + + LabeledDoubleSpinBox { + id: robotLField + + Layout.fillWidth: true + from: 0 + + label: "Robot Length (m)" + + bindedProperty: "item_robotLengthMeters" + bindTarget: widget + + stepSize: 0.1 + } + } + + SectionHeader { + label: "Field Settings" + } + + RowLayout { + uniformCellSizes: true + Layout.fillWidth: true + + LabeledCheckbox { + id: vertField + Layout.fillWidth: true + + label: "Use Vertical Field" + + bindedProperty: "item_useVerticalField" + bindTarget: widget + } + + LabeledCheckbox { + id: mirrorRedField + Layout.fillWidth: true + + label: "Mirror for Red" + + bindedProperty: "item_mirrorForRedAlliance" + bindTarget: widget + } + } + + LabeledComboBox { + id: fieldField // lol + Layout.fillWidth: true + + label: "Field Type" + choices: fieldChoices + + bindedProperty: "item_field" + bindTarget: widget + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } + } } diff --git a/widgets/sendable/StringChooser.qml b/widgets/sendable/StringChooser.qml index 9c7744d8..91a7b907 100644 --- a/widgets/sendable/StringChooser.qml +++ b/widgets/sendable/StringChooser.qml @@ -1,10 +1,12 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 -import QtQuick.Layouts 2.15 +import QtQuick.Layouts import QFRCDashboard BaseWidget { + id: widget + property string item_topic property int item_fontSize: 18 @@ -100,4 +102,88 @@ BaseWidget { topic = item_topic combo.update() } + + BaseConfigDialog { + id: config + + height: 300 + + function openDialog() { + topicField.open() + titleFontField.open() + fontField.open() + + open() + } + + onAccepted: { + topicField.accept() + titleFontField.accept() + fontField.accept() + } + + ColumnLayout { + id: layout + spacing: 25 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + + topMargin: config.headerHeight + 12 + bottomMargin: 45 + + leftMargin: 5 + rightMargin: 5 + } + + SectionHeader { + label: "Font Settings" + } + + RowLayout { + uniformCellSizes: true + + LabeledSpinBox { + Layout.fillWidth: true + + id: titleFontField + + label: "Title Font Size" + + bindedProperty: "item_titleFontSize" + bindTarget: widget + } + + LabeledSpinBox { + Layout.fillWidth: true + + id: fontField + + label: "Font Size" + + bindedProperty: "item_fontSize" + bindTarget: widget + } + } + + SectionHeader { + label: "NT Settings" + } + + LabeledTextField { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + id: topicField + + label: "Topic" + + bindedProperty: "item_topic" + bindTarget: widget + } + } + } }