diff --git a/Desktop/components/JASP/Widgets/ColumnBasicInfo.qml b/Desktop/components/JASP/Widgets/ColumnBasicInfo.qml index 2dd8b1f157..681c188f6d 100644 --- a/Desktop/components/JASP/Widgets/ColumnBasicInfo.qml +++ b/Desktop/components/JASP/Widgets/ColumnBasicInfo.qml @@ -94,7 +94,7 @@ Item values: columnModel.columnTypeValues currentValue: columnModel.currentColumnType onValueChanged: columnModel.currentColumnType = currentValue - controlMinWidth: 200 * jaspTheme.uiScale + fieldWidth: 200 * jaspTheme.uiScale controlLabel.width: leftColumn.labelWidth enabled: !columnModel.isVirtual @@ -108,7 +108,7 @@ Item values: columnModel.computedTypeValues currentValue: columnModel.computedType onValueChanged: columnModel.computedType = currentValue - controlMinWidth: 200 * jaspTheme.uiScale + fieldWidth: 200 * jaspTheme.uiScale controlLabel.width: leftColumn.labelWidth enabled: !columnModel.isVirtual && columnModel.computedTypeEditable diff --git a/QMLComponents/components/JASP/Controls/ComboBox.qml b/QMLComponents/components/JASP/Controls/ComboBox.qml index 9590a14490..675e6f6428 100644 --- a/QMLComponents/components/JASP/Controls/ComboBox.qml +++ b/QMLComponents/components/JASP/Controls/ComboBox.qml @@ -19,12 +19,12 @@ ComboBoxBase property alias currentLabel: comboBox.currentText property alias value: comboBox.currentValue property alias indexDefaultValue: comboBox.currentIndex - property alias fieldWidth: control.width + property alias fieldWidth: control.implicitWidth + property alias controlText: controlText property int textFormat: Text.AutoText property bool showVariableTypeIcon: containsVariables property var enabledOptions: [] property bool setLabelAbove: false - property int controlMinWidth: 0 property bool useExternalBorder: true property bool showBorder: true property bool showEmptyValueAsNormal: false @@ -32,46 +32,6 @@ ComboBoxBase property double controlXOffset: 0 property bool alignInGroup: !setLabelAbove - onControlMinWidthChanged: _resetWidth(textMetrics.width) - - - - function resetWidth(values) - { - var maxWidth = 0 - var maxValue = "" - textMetrics.initialized = false; - - if (addEmptyValue) - values.push(placeholderText) - - for (var i = 0; i < values.length; i++) - { - textMetrics.text = values[i] - if (textMetrics.width > maxWidth) - { - maxWidth = textMetrics.width - maxValue = values[i] - } - } - - textMetrics.text = maxValue; - textMetrics.initialized = true; - _resetWidth(maxWidth) - } - - function _resetWidth(maxTextWidth) - { - control.maxTextWidth = maxTextWidth - // The real field width is composed by the type icon (if displayed) + 2-padding + max width + 5-padding + dropdownIcon width + 2-padding - var newFieldWidth = (comboBox.showVariableTypeIcon ? contentIcon.x + contentIcon.width : 0) + (allowedTypeIcons.count > 0 ? allowedTypeIcons.width + jaspTheme.itemPadding : 0) + maxTextWidth + dropdownIcon.width + 9 * preferencesModel.uiScale - if (newFieldWidth < controlMinWidth) - newFieldWidth = controlMinWidth - - control.realFieldWidth = newFieldWidth - if (!fixedWidth) control.width = newFieldWidth; - } - Component.onCompleted: control.activated.connect(activated); Rectangle @@ -95,6 +55,7 @@ ComboBoxBase QTC.ComboBox { id: control + implicitWidth: longestFieldWidth + (allowedTypeIcons.count > 0 ? allowedTypeIcons.width + jaspTheme.contentMargin : 0) model: comboBox.model anchors { @@ -105,31 +66,25 @@ ComboBoxBase focus: true padding: 2 * preferencesModel.uiScale - width: 0 height: jaspTheme.comboBoxHeight font: jaspTheme.font property bool isEmptyValue: comboBox.addEmptyValue && comboBox.currentIndex === 0 property bool showEmptyValueStyle: !comboBox.showEmptyValueAsNormal && isEmptyValue - property double realFieldWidth: width - property double maxTextWidth: 0 + property double longestFieldWidth: (comboBox.showVariableTypeIcon ? contentIcon.x + contentIcon.width + jaspTheme.contentMargin : 0) + + textMetrics.width + 2 * jaspTheme.contentMargin TextMetrics { id: textMetrics font: control.font - - property bool initialized: false - - onWidthChanged: - { - if (initialized) - _resetWidth(width) - } + text: longestValue } contentItem: Rectangle { + id: contentRectangle color: jaspTheme.controlBackgroundColor + Image { id: contentIcon @@ -143,18 +98,19 @@ ComboBoxBase Text { - anchors.left: contentIcon.visible ? contentIcon.right : parent.left - anchors.leftMargin: 2 * preferencesModel.uiScale - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: control.showEmptyValueStyle ? parent.horizontalCenter : undefined + id: controlText + anchors + { + left: contentIcon.visible ? contentIcon.right : parent.left + leftMargin: 2 * preferencesModel.uiScale + right: allowedColumnsIcons.length > 0 ? allowedTypeIcons.left : parent.right + verticalCenter: parent.verticalCenter + //horizontalCenter: control.showEmptyValueStyle ? parent.horizontalCenter : undefined + } text: comboBox.currentText font: control.font color: (!enabled || control.showEmptyValueStyle) ? jaspTheme.grayDarker : jaspTheme.black - width: (fixedWidth ? widthWhenContralHasFixedWidth : control.maxTextWidth) + 5 * preferencesModel.uiScale elide: Text.ElideRight - - property double widthWhenContralHasFixedWidth: control.width - (x + dropdownIcon.width + 4 * preferencesModel.uiScale) // 4 = leftMargin + 2 padding right of dropdownIcon) - } AllowedTypeIcons @@ -208,15 +164,8 @@ ComboBoxBase popup: QTC.Popup { id: popupRoot - y: control.height - width: Math.max(control.realFieldWidth, fieldWidth) + scrollBar.width - - property real maxHeight: typeof mainWindowRoot !== 'undefined' ? mainWindowRoot.height // Case Dropdowns used in Desktop - : (typeof rcmdRoot !== 'undefined' ? rcmdRoot.height // Case Dropdown used in R Command - : (typeof backgroundForms !== 'undefined' ? backgroundForms.height // Case Dropdowns used in Analysis forms - : Infinity)) - height: Math.min(popupView.contentHeight + (padding*2), maxHeight) padding: 1 + implicitWidth: popupView.implicitWidth + scrollBar.width enter: Transition { NumberAnimation { property: "opacity"; from: 0.0; to: 1.0 } enabled: preferencesModel.animationsOn } @@ -236,16 +185,22 @@ ComboBoxBase } } - contentItem: ListView { id: popupView - width: popupRoot.width - scrollBar.width - height: popupRoot.height - model: control.popup.visible ? control.delegateModel : null + implicitWidth: Math.max(control.longestFieldWidth, control.width) + implicitHeight: Math.min(contentHeight, maxHeight) + model: control.delegateModel currentIndex: control.highlightedIndex clip: true + property real maxHeight: typeof mainWindowRoot !== 'undefined' ? mainWindowRoot.height // Case Dropdowns used in Desktop + : (typeof rcmdRoot !== 'undefined' ? rcmdRoot.height // Case Dropdown used in R Command + : (typeof backgroundForms !== 'undefined' ? backgroundForms.height // Case Dropdowns used in Analysis forms + : Infinity)) + + + Rectangle { anchors.centerIn: parent @@ -267,8 +222,8 @@ ComboBoxBase delegate: QTC.ItemDelegate { - height: jaspTheme.comboBoxHeight - width: popupView.width + implicitHeight: jaspTheme.comboBoxHeight + implicitWidth: popupView.width enabled: comboBox.enabledOptions.length == 0 || comboBox.enabledOptions.length <= index || comboBox.enabledOptions[index] contentItem: Rectangle diff --git a/QMLComponents/controls/comboboxbase.cpp b/QMLComponents/controls/comboboxbase.cpp index d15829c7d4..9c681c633d 100644 --- a/QMLComponents/controls/comboboxbase.cpp +++ b/QMLComponents/controls/comboboxbase.cpp @@ -19,7 +19,7 @@ #include "comboboxbase.h" #include "analysisform.h" #include "log.h" - +#include "jasptheme.h" ComboBoxBase::ComboBoxBase(QQuickItem* parent) : JASPListControl(parent), BoundControlBase(this) @@ -144,9 +144,6 @@ bool ComboBoxBase::isJsonValid(const Json::Value &optionValue) const void ComboBoxBase::setUp() { - if (property("fieldWidth").toInt() > 0) // If the fieldWidth is set, it means the width should be fixed and not dependent on the values of the dropdown. - _fixedWidth = true; - JASPListControl::setUp(); _model->resetTermsFromSources(); @@ -224,8 +221,31 @@ bool ComboBoxBase::_checkLevelsConstraints() void ComboBoxBase::_resetItemWidth() { - const Terms& terms = _model->terms(); - QMetaObject::invokeMethod(this, "resetWidth", Q_ARG(QVariant, QVariant(terms.asQList()))); + double maxWidth = 0; + QString longestValue; + + QFontMetricsF& metrics = JaspTheme::fontMetrics(); + + if (_addEmptyValue) + { + maxWidth = metrics.horizontalAdvance(_placeHolderText); + longestValue = _placeHolderText; + } + for (const Term& term : model()->terms()) + { + double termWidth = metrics.horizontalAdvance(term.asQString()); + if (maxWidth < termWidth) + { + maxWidth = termWidth; + longestValue = term.asQString(); + } + } + + if (_longestValue != longestValue) + { + _longestValue = longestValue; + emit longestValueChanged(); + } } void ComboBoxBase::setCurrentText(QString text) diff --git a/QMLComponents/controls/comboboxbase.h b/QMLComponents/controls/comboboxbase.h index 6e9648a9fd..292c9c90a7 100644 --- a/QMLComponents/controls/comboboxbase.h +++ b/QMLComponents/controls/comboboxbase.h @@ -35,7 +35,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase Q_PROPERTY( QString startValue READ startValue WRITE setStartValue NOTIFY startValueChanged ) Q_PROPERTY( QString currentColumnType READ currentColumnType NOTIFY currentColumnTypeChanged ) Q_PROPERTY( QString currentColumnTypeIcon READ currentColumnTypeIcon NOTIFY currentColumnTypeIconChanged ) - Q_PROPERTY( bool fixedWidth READ fixedWidth WRITE setFixedWidth NOTIFY fixedWidthChanged ) + Q_PROPERTY( QString longestValue READ longestValue NOTIFY longestValueChanged ) public: ComboBoxBase(QQuickItem* parent = nullptr); @@ -56,7 +56,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase const QString& currentColumnType() const { return _currentColumnType; } const QString& currentColumnTypeIcon() const { return _currentColumnTypeIcon;} int currentIndex() const { return _currentIndex; } - bool fixedWidth() const { return _fixedWidth; } + QString longestValue() const { return _longestValue; } std::vector usedVariables() const override; bool encodeValue() const override { return containsVariables(); } @@ -70,7 +70,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase void currentColumnTypeIconChanged(); void currentIndexChanged(); void activated(int index); - void fixedWidthChanged(); + void longestValueChanged(); protected slots: void termsChangedHandler() override; @@ -80,10 +80,10 @@ protected slots: void activatedSlot(int index); GENERIC_SET_FUNCTION(StartValue, _startValue, startValueChanged, QString ) - GENERIC_SET_FUNCTION(FixedWidth, _fixedWidth, fixedWidthChanged, bool ) protected: bool _checkLevelsConstraints() override; + void _setLongestValue(); ListModelLabelValueTerms* _model = nullptr; @@ -95,7 +95,7 @@ protected slots: _currentColumnTypeIcon; std::string _unusedInitialValue; int _currentIndex = -1; - bool _fixedWidth = false; + QString _longestValue; int _getStartIndex() const; void _resetItemWidth();