Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DropDown width issues solved #5753

Merged
merged 8 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Desktop/components/JASP/Widgets/ColumnBasicInfo.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down
105 changes: 30 additions & 75 deletions QMLComponents/components/JASP/Controls/ComboBox.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,19 @@ 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
boutinb marked this conversation as resolved.
Show resolved Hide resolved
boutinb marked this conversation as resolved.
Show resolved Hide resolved
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
property bool addLineAfterEmptyValue: false
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
Expand All @@ -95,6 +55,7 @@ ComboBoxBase
QTC.ComboBox
{
id: control
implicitWidth: longestFieldWidth + (allowedTypeIcons.count > 0 ? allowedTypeIcons.width + jaspTheme.contentMargin : 0)
model: comboBox.model
anchors
{
Expand All @@ -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 + indicator.width + 3 * 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
Expand All @@ -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
Expand Down Expand Up @@ -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 }

Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion QMLComponents/components/JASP/Controls/VariablesForm.qml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ VariablesFormBase
else if (isControlComboBox && widthSetByForm(control))
{
control.setLabelAbove = true
control.controlMinWidth = Qt.binding(function() {return variablesForm.listWidth; })
control.fieldWidth = Qt.binding(function() {return variablesForm.listWidth; })
}
}

Expand Down
35 changes: 29 additions & 6 deletions QMLComponents/controls/comboboxbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "comboboxbase.h"
#include "analysisform.h"
#include "log.h"

#include "jasptheme.h"

ComboBoxBase::ComboBoxBase(QQuickItem* parent)
: JASPListControl(parent), BoundControlBase(this)
Expand Down Expand Up @@ -78,6 +78,8 @@ void ComboBoxBase::bindTo(const Json::Value& value)
{
addControlError(tr("Unknown option %1 in DropDown %2").arg(tq(selectedValue)).arg(name()));
index = 0;
// 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
_unusedInitialValue = selectedValue;
}
index = int(std::distance(values.begin(), itr));
}
Expand Down Expand Up @@ -144,9 +146,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();
Expand Down Expand Up @@ -196,6 +195,7 @@ void ComboBoxBase::termsChangedHandler()
itr = lostValueItr;
_orgValue = _unusedInitialValue;
_unusedInitialValue = "";
clearControlError();
}
}

Expand Down Expand Up @@ -224,8 +224,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)
Expand Down
10 changes: 5 additions & 5 deletions QMLComponents/controls/comboboxbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<std::string> usedVariables() const override;
bool encodeValue() const override { return containsVariables(); }
Expand All @@ -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;
Expand All @@ -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();
boutinb marked this conversation as resolved.
Show resolved Hide resolved


ListModelLabelValueTerms* _model = nullptr;
Expand All @@ -95,7 +95,7 @@ protected slots:
_currentColumnTypeIcon;
std::string _unusedInitialValue;
int _currentIndex = -1;
bool _fixedWidth = false;
QString _longestValue;

int _getStartIndex() const;
void _resetItemWidth();
Expand Down
Loading