diff --git a/meshroom/ui/qml/GraphEditor/AttributeControls/ChoiceMulti.qml b/meshroom/ui/qml/GraphEditor/AttributeControls/ChoiceMulti.qml new file mode 100644 index 00000000..a4807b34 --- /dev/null +++ b/meshroom/ui/qml/GraphEditor/AttributeControls/ChoiceMulti.qml @@ -0,0 +1,41 @@ +import QtQuick +import QtQuick.Controls +import Controls + +/** + * A multi-checkboxes control with a current `value` (list of 0-N elements) and a list of possible `values`. + * Provides support for custom values (`value` elements not in `values`). + */ +Flow { + id: root + + required property var value + required property var values + property color customValueColor: "orange" + + signal toggled(var value, var checked) + + // Predefined possible values. + Repeater { + model: root.values + delegate: CheckBox { + text: modelData + checked: root.value.includes(modelData) + onToggled: root.toggled(modelData, checked) + } + } + + // Custom elements outside the predefined possible values. + Repeater { + model: root.value.filter(v => !root.values.includes(v)) + delegate: CheckBox { + text: modelData + palette.text: root.customValueColor + font.italic: true + checked: true + ToolTip.text: "Custom value" + ToolTip.visible: hovered + onToggled: root.toggled(modelData, checked) + } + } +} diff --git a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml index e8ad4fe1..5a6ecbed 100644 --- a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml +++ b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml @@ -209,7 +209,7 @@ RowLayout { case "PushButtonParam": return pushButtonComponent case "ChoiceParam": - return attribute.desc.exclusive ? choiceComponent : multiChoiceComponent + return attribute.desc.exclusive ? choiceComponent : choiceMultiComponent case "IntParam": return sliderComponent case "FloatParam": if (attribute.desc.semantic === 'color/hue') @@ -484,25 +484,21 @@ RowLayout { } Component { - id: multiChoiceComponent - Flow { - Repeater { - id: checkboxRepeater - model: attribute.values - delegate: CheckBox { - enabled: root.editable - text: modelData - checked: attribute.value.indexOf(modelData) >= 0 - onToggled: { - var t = attribute.value - if (!checked) { - t.splice(t.indexOf(modelData), 1) // Remove element - } else { - t.push(modelData) // Add element - } - _reconstruction.setAttribute(attribute, t) - } + id: choiceMultiComponent + + AttributeControls.ChoiceMulti { + value: root.attribute.value + values: root.attribute.values + enabled: root.editable + customValueColor: Colors.orange + onToggled: (value, checked) => { + var currentValue = root.attribute.value; + if (!checked) { + currentValue.splice(currentValue.indexOf(value), 1); + } else { + currentValue.push(value); } + _reconstruction.setAttribute(attribute, currentValue); } } }