Enhance sizing in StandardDialogs

It's very smart now, and will look beautiful in (hopefully, or at least almost) all possible cases.

Also implemented updating size of PopupView in dialog mode when content size changed. This was necessary to make the StandardDialogs work.
This commit is contained in:
Casper Jeukendrup 2021-12-13 04:16:40 +01:00
parent b8de8be08d
commit e6c13cdd6b
No known key found for this signature in database
GPG key ID: 6C571BEF59E722DD
6 changed files with 105 additions and 112 deletions

View file

@ -41,6 +41,9 @@ StyledDialogView {
property var buttons: [ { "buttonId": 1, "title": qsTrc("global", "OK") } ]
property alias defaultButtonId: content.defaultButtonId
contentWidth: content.implicitWidth
contentHeight: content.implicitHeight
margins: 16
onOpened: {
@ -49,21 +52,11 @@ StyledDialogView {
StandardDialogPanel {
id: content
anchors.fill: parent
navigation.section: root.navigationSection
buttons: root.buttons
onContentWidthChanged: {
root.contentWidth = Math.max(Math.min(491, content.contentWidth), 306)
}
onContentHeightChanged: {
root.contentHeight = Math.max(104, content.contentHeight)
}
onClicked: function(buttonId, showAgain) {
root.ret = { "errcode": 0, "value": { "buttonId": buttonId, "showAgain": showAgain}}
root.hide()

View file

@ -25,7 +25,7 @@ import QtQuick.Layouts 1.15
import MuseScore.Ui 1.0
import MuseScore.UiComponents 1.0
Rectangle {
RowLayout {
id: root
property string type: "INFO" // "QUESTION", "INFO", "WARNING", "ERROR"
@ -42,15 +42,10 @@ Rectangle {
property var buttons: []
property int defaultButtonId: 0
property real contentWidth: Math.max(textContent.contentWidth, buttons.width)
property real contentHeight: content.contentHeight
property alias navigation: navPanel
signal clicked(int buttonId, bool showAgain)
color: ui.theme.backgroundPrimaryColor
function onOpened() {
var btn = root.firstFocusBtn()
btn.navigation.requestActive()
@ -112,126 +107,109 @@ Rectangle {
name: root.title + " " + root.text + " " + root.firstFocusBtn().text + " " + qsTrc("global", "Button")
}
ColumnLayout {
id: content
spacing: 27
anchors.fill: parent
StyledIconLabel {
id: icon
property int contentHeight: childrenRect.height
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: 48
Layout.preferredHeight: 48
spacing: 16
font.pixelSize: 48
iconCode: root.standardIcon(root.type)
RowLayout {
id: textContent
visible: root.withIcon && !isEmpty
}
property int contentWidth: (icon.visible ? icon.width + textContent.spacing : 0) + textColumn._preferredWidth
Column {
Layout.fillWidth: true
Layout.preferredWidth: content.width
Layout.preferredHeight: childrenRect.height
// Unclear why "+ 1" is needed; apparently implicitWidth is incorrect
readonly property real textsImplicitWidth: Math.max(titleLabel.implicitWidth,
textLabel.implicitWidth,
withShowAgainCheckBox.implicitWidth) + 1
spacing: 28
// Allow the text to make the dialog wider, but not too much wider
readonly property real textsImplicitWidthBounded: Math.min(420, textsImplicitWidth)
StyledIconLabel {
id: icon
// But if the buttons need more space, then the dialog becomes as wide as necessary
Layout.preferredWidth: Math.max(buttons.width, textsImplicitWidthBounded)
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: 48
Layout.preferredHeight: 48
spacing: 18
font.pixelSize: 48
iconCode: root.standardIcon(root.type)
Column {
width: parent.width
height: Math.max(implicitHeight, 32)
spacing: 18
visible: root.withIcon && !isEmpty
StyledTextLabel {
id: titleLabel
width: parent.width
font: ui.theme.largeBodyBoldFont
horizontalAlignment: Text.AlignLeft
maximumLineCount: 2
wrapMode: Text.Wrap
visible: !isEmpty
}
Column {
id: textColumn
StyledTextLabel {
id: textLabel
width: parent.width
property int _preferredWidth: Math.max(Math.min(titleLabel.implicitWidth, 420),
Math.min(textLabel.implicitWidth, 420))
horizontalAlignment: Text.AlignLeft
maximumLineCount: 3
wrapMode: Text.Wrap
Layout.preferredWidth: _preferredWidth + /*todo*/ 76
Layout.preferredHeight: childrenRect.height
visible: !isEmpty
}
spacing: 16
CheckBox {
id: withShowAgainCheckBox
width: parent.width
visible: Boolean(root.withShowAgain)
StyledTextLabel {
id: titleLabel
text: qsTrc("ui", "Show this message again")
checked: true
width: parent._preferredWidth + /*todo*/ 4
font: ui.theme.largeBodyBoldFont
horizontalAlignment: Text.AlignLeft
maximumLineCount: 2
wrapMode: Text.Wrap
visible: !isEmpty
}
StyledTextLabel {
id: textLabel
width: parent._preferredWidth + /*todo*/ 4
horizontalAlignment: Text.AlignLeft
maximumLineCount: 3
wrapMode: Text.Wrap
visible: !isEmpty
}
CheckBox {
id: withShowAgainCheckBox
Layout.fillWidth: true
text: qsTrc("ui", "Show this message again")
checked: true
visible: Boolean(root.withShowAgain)
onClicked: {
checked = !checked
}
onClicked: {
checked = !checked
}
}
}
Item {
Layout.preferredHeight: 30
Layout.preferredWidth: content.width
ListView {
id: buttons
anchors.right: parent.right
spacing: 12
ListView {
id: buttons
anchors.right: parent.right
spacing: 12
width: contentWidth
height: contentHeight
contentHeight: 30
width: contentWidth
height: contentHeight
model: root.buttons
orientation: Qt.Horizontal
interactive: false
model: root.buttons
orientation: Qt.Horizontal
delegate: FlatButton {
navigation.panel: navPanel
navigation.column: model.index
delegate: FlatButton {
navigation.panel: navPanel
navigation.column: model.index
//! NOTE See description about AccessibleItem { id: accessibleInfo }
accessible.ignored: true
navigation.onActiveChanged: {
if (navigation.active) {
accessible.ignored = false
}
//! NOTE See description about AccessibleItem { id: accessibleInfo }
accessible.ignored: true
navigation.onActiveChanged: {
if (navigation.active) {
accessible.ignored = false
}
}
text: modelData.title
accentButton: Boolean(modelData.accent)
text: modelData.title
accentButton: Boolean(modelData.accent)
onClicked: {
root.clicked(modelData.buttonId, withShowAgainCheckBox.checked)
}
onClicked: {
root.clicked(modelData.buttonId, withShowAgainCheckBox.checked)
}
}
}

View file

@ -103,6 +103,10 @@ void PopupView::componentComplete()
m_window->setOnHidden([this]() { onHidden(); });
m_window->setContent(m_contentItem);
if (isDialog()) {
connect(m_window, &IPopupWindow::sizeChanged, this, &PopupView::updateSize);
}
// TODO: Can't use new `connect` syntax because the IPopupWindow::aboutToClose
// has a parameter of type QQuickCloseEvent, which is not public, so we
// can't include any header for it and it will always be an incomplete
@ -175,11 +179,7 @@ void PopupView::open()
qWindow->setModality(Qt::NonModal);
#endif
QRect winRect = m_window->geometry();
qWindow->setMinimumSize(winRect.size());
if (!m_resizable) {
qWindow->setMaximumSize(winRect.size());
}
updateSize();
}
m_window->show(m_globalPos.toPoint());
@ -574,6 +574,24 @@ QRect PopupView::currentScreenGeometry() const
return currentScreen->availableGeometry();
}
void PopupView::updateSize()
{
if (!isDialog()) {
return;
}
QWindow* qWindow = this->qWindow();
if (!qWindow) {
return;
}
QSize size = qWindow->size();
qWindow->setMinimumSize(size);
if (!m_resizable) {
qWindow->setMaximumSize(size);
}
}
void PopupView::updatePosition()
{
const QQuickItem* parent = parentItem();

View file

@ -198,6 +198,7 @@ protected:
void setErrCode(Ret::Code code);
QRect currentScreenGeometry() const;
void updateSize();
void updatePosition();
void updateContentPosition();

View file

@ -61,6 +61,7 @@ public:
virtual void setOnHidden(const std::function<void()>& callback) = 0;
signals:
void sizeChanged();
void aboutToClose(QQuickCloseEvent* event);
};
}

View file

@ -91,6 +91,7 @@ void PopupWindow_QQuickView::setContent(QQuickItem* item)
}
if (item->implicitWidth() != m_view->width()) {
m_view->resize(item->implicitWidth(), item->implicitHeight());
emit sizeChanged();
}
});
@ -100,6 +101,7 @@ void PopupWindow_QQuickView::setContent(QQuickItem* item)
}
if (item->implicitHeight() != m_view->height()) {
m_view->resize(item->implicitWidth(), item->implicitHeight());
emit sizeChanged();
}
});
}