Skip to content

Commit 9d3e69b

Browse files
boutinbJorisGoosen
andauthored
DropDown width issues solved (#5753)
* DropDown width issues solved * Replace controlMinWidth by fieldWidth in VariablesForm * Add indicator to calculate dropdown width * Fix DropDown initialization in MetaAnalysis In the Effect Size Computation of the Meta Analysis module, the dropdowns in a ComponentList depends on each other for their values. TO solve this, just use the _unusedInitialValue. * set height of popup otherwise it doesnt get moved up on too big for screen * Update QMLComponents/controls/comboboxbase.h Co-authored-by: Joris Goosen <[email protected]> * ok so padding needs to be included in the implicitsize of the popup * Remove controlText alias --------- Co-authored-by: Joris Goosen <[email protected]>
1 parent 0765df3 commit 9d3e69b

File tree

5 files changed

+70
-93
lines changed

5 files changed

+70
-93
lines changed

Desktop/components/JASP/Widgets/ColumnBasicInfo.qml

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ Item
9494
values: columnModel.columnTypeValues
9595
currentValue: columnModel.currentColumnType
9696
onValueChanged: columnModel.currentColumnType = currentValue
97-
controlMinWidth: 200 * jaspTheme.uiScale
97+
fieldWidth: 200 * jaspTheme.uiScale
9898
controlLabel.width: leftColumn.labelWidth
9999
enabled: !columnModel.isVirtual
100100

@@ -108,7 +108,7 @@ Item
108108
values: columnModel.computedTypeValues
109109
currentValue: columnModel.computedType
110110
onValueChanged: columnModel.computedType = currentValue
111-
controlMinWidth: 200 * jaspTheme.uiScale
111+
fieldWidth: 200 * jaspTheme.uiScale
112112

113113
controlLabel.width: leftColumn.labelWidth
114114
enabled: !columnModel.isVirtual && columnModel.computedTypeEditable

QMLComponents/components/JASP/Controls/ComboBox.qml

+34-79
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import QtQuick
2-
import QtQuick.Controls as QTC
2+
import QtQuick.Controls
33
import QtQuick.Layouts
44
import JASP
55

@@ -19,59 +19,18 @@ ComboBoxBase
1919
property alias currentLabel: comboBox.currentText
2020
property alias value: comboBox.currentValue
2121
property alias indexDefaultValue: comboBox.currentIndex
22-
property alias fieldWidth: control.width
22+
property alias fieldWidth: control.implicitWidth
2323
property int textFormat: Text.AutoText
2424
property bool showVariableTypeIcon: containsVariables
2525
property var enabledOptions: []
2626
property bool setLabelAbove: false
27-
property int controlMinWidth: 0
2827
property bool useExternalBorder: true
2928
property bool showBorder: true
3029
property bool showEmptyValueAsNormal: false
3130
property bool addLineAfterEmptyValue: false
3231
property double controlXOffset: 0
3332
property bool alignInGroup: !setLabelAbove
3433

35-
onControlMinWidthChanged: _resetWidth(textMetrics.width)
36-
37-
38-
39-
function resetWidth(values)
40-
{
41-
var maxWidth = 0
42-
var maxValue = ""
43-
textMetrics.initialized = false;
44-
45-
if (addEmptyValue)
46-
values.push(placeholderText)
47-
48-
for (var i = 0; i < values.length; i++)
49-
{
50-
textMetrics.text = values[i]
51-
if (textMetrics.width > maxWidth)
52-
{
53-
maxWidth = textMetrics.width
54-
maxValue = values[i]
55-
}
56-
}
57-
58-
textMetrics.text = maxValue;
59-
textMetrics.initialized = true;
60-
_resetWidth(maxWidth)
61-
}
62-
63-
function _resetWidth(maxTextWidth)
64-
{
65-
control.maxTextWidth = maxTextWidth
66-
// The real field width is composed by the type icon (if displayed) + 2-padding + max width + 5-padding + dropdownIcon width + 2-padding
67-
var newFieldWidth = (comboBox.showVariableTypeIcon ? contentIcon.x + contentIcon.width : 0) + (allowedTypeIcons.count > 0 ? allowedTypeIcons.width + jaspTheme.itemPadding : 0) + maxTextWidth + dropdownIcon.width + 9 * preferencesModel.uiScale
68-
if (newFieldWidth < controlMinWidth)
69-
newFieldWidth = controlMinWidth
70-
71-
control.realFieldWidth = newFieldWidth
72-
if (!fixedWidth) control.width = newFieldWidth;
73-
}
74-
7534
Component.onCompleted: control.activated.connect(activated);
7635

7736
Rectangle
@@ -92,9 +51,10 @@ ComboBoxBase
9251
}
9352
}
9453

95-
QTC.ComboBox
54+
ComboBox
9655
{
9756
id: control
57+
implicitWidth: longestFieldWidth + (allowedTypeIcons.count > 0 ? allowedTypeIcons.width + jaspTheme.contentMargin : 0)
9858
model: comboBox.model
9959
anchors
10060
{
@@ -105,31 +65,25 @@ ComboBoxBase
10565

10666
focus: true
10767
padding: 2 * preferencesModel.uiScale
108-
width: 0
10968
height: jaspTheme.comboBoxHeight
11069
font: jaspTheme.font
11170
property bool isEmptyValue: comboBox.addEmptyValue && comboBox.currentIndex === 0
11271
property bool showEmptyValueStyle: !comboBox.showEmptyValueAsNormal && isEmptyValue
113-
property double realFieldWidth: width
114-
property double maxTextWidth: 0
72+
property double longestFieldWidth: (comboBox.showVariableTypeIcon ? contentIcon.x + contentIcon.width + jaspTheme.contentMargin : 0) +
73+
textMetrics.width + indicator.width + 3 * jaspTheme.contentMargin
11574

11675
TextMetrics
11776
{
11877
id: textMetrics
11978
font: control.font
120-
121-
property bool initialized: false
122-
123-
onWidthChanged:
124-
{
125-
if (initialized)
126-
_resetWidth(width)
127-
}
79+
text: longestValue
12880
}
12981

13082
contentItem: Rectangle
13183
{
84+
id: contentRectangle
13285
color: jaspTheme.controlBackgroundColor
86+
13387
Image
13488
{
13589
id: contentIcon
@@ -143,18 +97,19 @@ ComboBoxBase
14397

14498
Text
14599
{
146-
anchors.left: contentIcon.visible ? contentIcon.right : parent.left
147-
anchors.leftMargin: 2 * preferencesModel.uiScale
148-
anchors.verticalCenter: parent.verticalCenter
149-
anchors.horizontalCenter: control.showEmptyValueStyle ? parent.horizontalCenter : undefined
100+
id: controlText
101+
anchors
102+
{
103+
left: contentIcon.visible ? contentIcon.right : parent.left
104+
leftMargin: 2 * preferencesModel.uiScale
105+
right: allowedColumnsIcons.length > 0 ? allowedTypeIcons.left : parent.right
106+
verticalCenter: parent.verticalCenter
107+
//horizontalCenter: control.showEmptyValueStyle ? parent.horizontalCenter : undefined
108+
}
150109
text: comboBox.currentText
151110
font: control.font
152111
color: (!enabled || control.showEmptyValueStyle) ? jaspTheme.grayDarker : jaspTheme.black
153-
width: (fixedWidth ? widthWhenContralHasFixedWidth : control.maxTextWidth) + 5 * preferencesModel.uiScale
154112
elide: Text.ElideRight
155-
156-
property double widthWhenContralHasFixedWidth: control.width - (x + dropdownIcon.width + 4 * preferencesModel.uiScale) // 4 = leftMargin + 2 padding right of dropdownIcon)
157-
158113
}
159114

160115
AllowedTypeIcons
@@ -205,18 +160,12 @@ ComboBoxBase
205160
radius: jaspTheme.jaspControlHighlightWidth
206161
}
207162

208-
popup: QTC.Popup
163+
popup: Popup
209164
{
210165
id: popupRoot
211-
y: control.height
212-
width: Math.max(control.realFieldWidth, fieldWidth) + scrollBar.width
213-
214-
property real maxHeight: typeof mainWindowRoot !== 'undefined' ? mainWindowRoot.height // Case Dropdowns used in Desktop
215-
: (typeof rcmdRoot !== 'undefined' ? rcmdRoot.height // Case Dropdown used in R Command
216-
: (typeof backgroundForms !== 'undefined' ? backgroundForms.height // Case Dropdowns used in Analysis forms
217-
: Infinity))
218-
height: Math.min(popupView.contentHeight + (padding*2), maxHeight)
219166
padding: 1
167+
implicitWidth: popupView.implicitWidth + scrollBar.width + 2*padding
168+
implicitHeight: popupView.implicitHeight + 2 * padding
220169

221170
enter: Transition { NumberAnimation { property: "opacity"; from: 0.0; to: 1.0 } enabled: preferencesModel.animationsOn }
222171

@@ -236,16 +185,22 @@ ComboBoxBase
236185
}
237186
}
238187

239-
240188
contentItem: ListView
241189
{
242190
id: popupView
243-
width: popupRoot.width - scrollBar.width
244-
height: popupRoot.height
245-
model: control.popup.visible ? control.delegateModel : null
191+
implicitWidth: Math.max(control.longestFieldWidth, control.width)
192+
implicitHeight: Math.min(contentHeight, maxHeight)
193+
model: control.delegateModel
246194
currentIndex: control.highlightedIndex
247195
clip: true
248196

197+
property real maxHeight: typeof mainWindowRoot !== 'undefined' ? mainWindowRoot.height // Case Dropdowns used in Desktop
198+
: (typeof rcmdRoot !== 'undefined' ? rcmdRoot.height // Case Dropdown used in R Command
199+
: (typeof backgroundForms !== 'undefined' ? backgroundForms.height // Case Dropdowns used in Analysis forms
200+
: Infinity))
201+
202+
203+
249204
Rectangle
250205
{
251206
anchors.centerIn: parent
@@ -265,10 +220,10 @@ ComboBoxBase
265220
}
266221
}
267222

268-
delegate: QTC.ItemDelegate
223+
delegate: ItemDelegate
269224
{
270-
height: jaspTheme.comboBoxHeight
271-
width: popupView.width
225+
implicitHeight: jaspTheme.comboBoxHeight
226+
implicitWidth: popupView.width
272227
enabled: comboBox.enabledOptions.length == 0 || comboBox.enabledOptions.length <= index || comboBox.enabledOptions[index]
273228

274229
contentItem: Rectangle

QMLComponents/components/JASP/Controls/VariablesForm.qml

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ VariablesFormBase
111111
else if (isControlComboBox && widthSetByForm(control))
112112
{
113113
control.setLabelAbove = true
114-
control.controlMinWidth = Qt.binding(function() {return variablesForm.listWidth; })
114+
control.fieldWidth = Qt.binding(function() {return variablesForm.listWidth; })
115115
}
116116
}
117117

QMLComponents/controls/comboboxbase.cpp

+29-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "comboboxbase.h"
2020
#include "analysisform.h"
2121
#include "log.h"
22-
22+
#include "jasptheme.h"
2323

2424
ComboBoxBase::ComboBoxBase(QQuickItem* parent)
2525
: JASPListControl(parent), BoundControlBase(this)
@@ -78,6 +78,8 @@ void ComboBoxBase::bindTo(const Json::Value& value)
7878
{
7979
addControlError(tr("Unknown option %1 in DropDown %2").arg(tq(selectedValue)).arg(name()));
8080
index = 0;
81+
// Maybe the values will be reset afterwards due to some QML/JavaScript dependencies: use this selectedValue if the model is reset during the initialization of the form
82+
_unusedInitialValue = selectedValue;
8183
}
8284
index = int(std::distance(values.begin(), itr));
8385
}
@@ -144,9 +146,6 @@ bool ComboBoxBase::isJsonValid(const Json::Value &optionValue) const
144146

145147
void ComboBoxBase::setUp()
146148
{
147-
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.
148-
_fixedWidth = true;
149-
150149
JASPListControl::setUp();
151150

152151
_model->resetTermsFromSources();
@@ -196,6 +195,7 @@ void ComboBoxBase::termsChangedHandler()
196195
itr = lostValueItr;
197196
_orgValue = _unusedInitialValue;
198197
_unusedInitialValue = "";
198+
clearControlError();
199199
}
200200
}
201201

@@ -224,8 +224,31 @@ bool ComboBoxBase::_checkLevelsConstraints()
224224

225225
void ComboBoxBase::_resetItemWidth()
226226
{
227-
const Terms& terms = _model->terms();
228-
QMetaObject::invokeMethod(this, "resetWidth", Q_ARG(QVariant, QVariant(terms.asQList())));
227+
double maxWidth = 0;
228+
QString longestValue;
229+
230+
QFontMetricsF& metrics = JaspTheme::fontMetrics();
231+
232+
if (_addEmptyValue)
233+
{
234+
maxWidth = metrics.horizontalAdvance(_placeHolderText);
235+
longestValue = _placeHolderText;
236+
}
237+
for (const Term& term : model()->terms())
238+
{
239+
double termWidth = metrics.horizontalAdvance(term.asQString());
240+
if (maxWidth < termWidth)
241+
{
242+
maxWidth = termWidth;
243+
longestValue = term.asQString();
244+
}
245+
}
246+
247+
if (_longestValue != longestValue)
248+
{
249+
_longestValue = longestValue;
250+
emit longestValueChanged();
251+
}
229252
}
230253

231254
void ComboBoxBase::setCurrentText(QString text)

QMLComponents/controls/comboboxbase.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase
3535
Q_PROPERTY( QString startValue READ startValue WRITE setStartValue NOTIFY startValueChanged )
3636
Q_PROPERTY( QString currentColumnType READ currentColumnType NOTIFY currentColumnTypeChanged )
3737
Q_PROPERTY( QString currentColumnTypeIcon READ currentColumnTypeIcon NOTIFY currentColumnTypeIconChanged )
38-
Q_PROPERTY( bool fixedWidth READ fixedWidth WRITE setFixedWidth NOTIFY fixedWidthChanged )
38+
Q_PROPERTY( QString longestValue READ longestValue NOTIFY longestValueChanged )
3939

4040
public:
4141
ComboBoxBase(QQuickItem* parent = nullptr);
@@ -56,7 +56,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase
5656
const QString& currentColumnType() const { return _currentColumnType; }
5757
const QString& currentColumnTypeIcon() const { return _currentColumnTypeIcon;}
5858
int currentIndex() const { return _currentIndex; }
59-
bool fixedWidth() const { return _fixedWidth; }
59+
QString longestValue() const { return _longestValue; }
6060

6161
std::vector<std::string> usedVariables() const override;
6262
bool encodeValue() const override { return containsVariables(); }
@@ -70,7 +70,7 @@ class ComboBoxBase : public JASPListControl, public BoundControlBase
7070
void currentColumnTypeIconChanged();
7171
void currentIndexChanged();
7272
void activated(int index);
73-
void fixedWidthChanged();
73+
void longestValueChanged();
7474

7575
protected slots:
7676
void termsChangedHandler() override;
@@ -80,7 +80,6 @@ protected slots:
8080
void activatedSlot(int index);
8181

8282
GENERIC_SET_FUNCTION(StartValue, _startValue, startValueChanged, QString )
83-
GENERIC_SET_FUNCTION(FixedWidth, _fixedWidth, fixedWidthChanged, bool )
8483

8584
protected:
8685
bool _checkLevelsConstraints() override;
@@ -95,7 +94,7 @@ protected slots:
9594
_currentColumnTypeIcon;
9695
std::string _unusedInitialValue;
9796
int _currentIndex = -1;
98-
bool _fixedWidth = false;
97+
QString _longestValue;
9998

10099
int _getStartIndex() const;
101100
void _resetItemWidth();

0 commit comments

Comments
 (0)