QmlDesigner: Add a SplitView for the MaterialEditor preview

* Also fixes that the image provider couldn't provide image for invalid
requests.

Task-number: QDS-12929
Change-Id: I172873880e30bbd6872f391f79692347f5697e6c
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Ali Kianian
2024-06-06 11:56:19 +03:00
parent 98c765d6fc
commit acdcf0c459
6 changed files with 96 additions and 48 deletions

View File

@@ -130,8 +130,8 @@ ColumnLayout {
orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical
handle: Rectangle { handle: Rectangle {
implicitWidth: splitView.orientation === Qt.Horizontal ? 6 : splitView.width implicitWidth: splitView.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : splitView.width
implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : 6 implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : StudioTheme.Values.splitterThickness
color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction
: (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover : (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover
: "transparent") : "transparent")

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick import QtQuick
import QtCore
import HelperWidgets import HelperWidgets
Item { Item {
@@ -42,6 +43,12 @@ Item {
onToolBarAction: (action) => root.toolBarAction(action) onToolBarAction: (action) => root.toolBarAction(action)
} }
Settings {
id: settings
property var topSection
}
PropertyEditorPane { PropertyEditorPane {
id: itemPane id: itemPane
@@ -52,8 +59,12 @@ Item {
clip: true clip: true
headerComponent: MaterialEditorTopSection { headerComponent: MaterialEditorTopSection {
id: topSection
onPreviewEnvChanged: root.previewEnvChanged(previewEnv) onPreviewEnvChanged: root.previewEnvChanged(previewEnv)
onPreviewModelChanged: root.previewModelChanged(previewModel) onPreviewModelChanged: root.previewModelChanged(previewModel)
Component.onCompleted: topSection.restoreState(settings.topSection)
Component.onDestruction: settings.topSection = topSection.saveState()
} }
DynamicPropertiesSection { DynamicPropertiesSection {

View File

@@ -8,17 +8,16 @@ import HelperWidgets as HelperWidgets
import StudioControls as StudioControls import StudioControls as StudioControls
import StudioTheme as StudioTheme import StudioTheme as StudioTheme
ColumnLayout { SplitView {
id: root id: root
property string previewEnv property string previewEnv
property string previewModel property string previewModel
property real __horizontalSpacing: 5 property real __spacing: 5
property StudioTheme.ControlStyle buttonStyle: StudioTheme.ViewBarButtonStyle { property StudioTheme.ControlStyle buttonStyle: StudioTheme.ViewBarButtonStyle {
//This is how you can override stuff from the control styles //This is how you can override stuff from the control styles
controlSize: Qt.size(optionsToolbar.height, optionsToolbar.height)
baseIconFontSize: StudioTheme.Values.bigIconFontSize baseIconFontSize: StudioTheme.Values.bigIconFontSize
} }
@@ -38,7 +37,17 @@ ColumnLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
Item { width: 1; height: 5 } // spacer implicitHeight: previewRect.implicitHeight + nameSection.implicitHeight
orientation: Qt.Vertical
handle: Rectangle {
implicitWidth: root.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : root.width
implicitHeight: root.orientation === Qt.Horizontal ? root.height : StudioTheme.Values.splitterThickness
color: SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction
: (SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover
: "transparent")
}
StudioControls.Menu { StudioControls.Menu {
id: modelMenu id: modelMenu
@@ -118,44 +127,13 @@ ColumnLayout {
} }
} }
Row {
id: optionsToolbar
Layout.preferredHeight: 40
Layout.fillWidth: true
leftPadding: root.__horizontalSpacing
StudioControls.AbstractButton {
id: pinButton
style: root.buttonStyle
iconSize: StudioTheme.Values.bigFont
buttonIcon: pinButton.checked ? StudioTheme.Constants.pin : StudioTheme.Constants.unpin
checkable: true
checked: itemPane.headerDocked
onCheckedChanged: itemPane.headerDocked = pinButton.checked
}
HelperWidgets.AbstractButton {
style: root.buttonStyle
buttonIcon: StudioTheme.Constants.textures_medium
tooltip: qsTr("Select preview environment.")
onClicked: envMenu.popup()
}
HelperWidgets.AbstractButton {
style: root.buttonStyle
buttonIcon: StudioTheme.Constants.cube_medium
tooltip: qsTr("Select preview model.")
onClicked: modelMenu.popup()
}
}
Rectangle { Rectangle {
id: previewRect id: previewRect
Layout.fillWidth: true SplitView.fillWidth: true
Layout.minimumWidth: 152 SplitView.minimumWidth: 152
SplitView.preferredHeight: Math.min(root.width * 0.75, 400)
SplitView.minimumHeight: 150
implicitHeight: materialPreview.height implicitHeight: materialPreview.height
clip: true clip: true
@@ -165,7 +143,7 @@ ColumnLayout {
id: materialPreview id: materialPreview
width: root.width width: root.width
height: Math.min(materialPreview.width * 0.75, 400) height: previewRect.height
anchors.centerIn: parent anchors.centerIn: parent
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
@@ -176,13 +154,66 @@ ColumnLayout {
sourceSize.width: materialPreview.width sourceSize.width: materialPreview.width
sourceSize.height: materialPreview.height sourceSize.height: materialPreview.height
Rectangle {
id: toolbarRect
radius: 10
color: StudioTheme.Values.themeToolbarBackground
width: optionsToolbar.width + 2 * toolbarRect.radius
height: optionsToolbar.height + toolbarRect.radius
anchors.left: parent.left
anchors.leftMargin: -toolbarRect.radius
anchors.verticalCenter: parent.verticalCenter
Column {
id: optionsToolbar
spacing: root.__spacing
anchors.centerIn: parent
anchors.horizontalCenterOffset: root.__spacing
HelperWidgets.AbstractButton {
id: pinButton
style: buttonStyle
buttonIcon: pinButton.checked ? StudioTheme.Constants.pin : StudioTheme.Constants.unpin
checkable: true
checked: itemPane.headerDocked
onCheckedChanged: itemPane.headerDocked = pinButton.checked
}
HelperWidgets.AbstractButton {
id: previewEnvMenuButton
style: buttonStyle
buttonIcon: StudioTheme.Constants.textures_medium
tooltip: qsTr("Select preview environment.")
onClicked: envMenu.popup()
}
HelperWidgets.AbstractButton {
id: previewModelMenuButton
style: buttonStyle
buttonIcon: StudioTheme.Constants.cube_medium
tooltip: qsTr("Select preview model.")
onClicked: modelMenu.popup()
}
}
}
} }
} }
HelperWidgets.Section { HelperWidgets.Section {
id: nameSection
// Section with hidden header is used so properties are aligned with the other sections' properties // Section with hidden header is used so properties are aligned with the other sections' properties
hideHeader: true hideHeader: true
Layout.fillWidth: true SplitView.fillWidth: true
SplitView.preferredHeight: implicitHeight
SplitView.maximumHeight: implicitHeight
bottomPadding: StudioTheme.Values.sectionPadding * 2
collapsible: false collapsible: false
HelperWidgets.SectionLayout { HelperWidgets.SectionLayout {
@@ -202,7 +233,7 @@ ColumnLayout {
showExtendedFunctionButton: false showExtendedFunctionButton: false
// allow only alphanumeric characters, underscores, no space at start, and 1 space between words // allow only alphanumeric characters, underscores, no space at start, and 1 space between words
validator: HelperWidgets.RegExpValidator { regExp: /^(\w+\s)*\w+$/ } validator: RegularExpressionValidator { regularExpression: /^(\w+\s)*\w+$/ }
} }
HelperWidgets.ExpandingSpacer {} HelperWidgets.ExpandingSpacer {}
@@ -211,9 +242,9 @@ ColumnLayout {
HelperWidgets.PropertyLabel { text: qsTr("Type") } HelperWidgets.PropertyLabel { text: qsTr("Type") }
HelperWidgets.SecondColumnLayout { HelperWidgets.SecondColumnLayout {
HelperWidgets.Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth } HelperWidgets.Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
HelperWidgets.ComboBox { HelperWidgets.ComboBox {
currentIndex: possibleTypeIndex currentIndex: possibleTypeIndex
model: possibleTypes model: possibleTypes
showExtendedFunctionButton: false showExtendedFunctionButton: false

View File

@@ -57,6 +57,7 @@ Rectangle {
bottom: itemPane.bottom bottom: itemPane.bottom
left: itemPane.left left: itemPane.left
right: itemPane.right right: itemPane.right
topMargin: dockedHeaderLoader.active ? 2 : 0
} }
interactive: !Controller.contextMenuOpened interactive: !Controller.contextMenuOpened
@@ -74,6 +75,7 @@ Rectangle {
active: !itemPane.headerDocked active: !itemPane.headerDocked
sourceComponent: itemPane.headerComponent sourceComponent: itemPane.headerComponent
visible: active
HeaderBackground{} HeaderBackground{}
} }

View File

@@ -126,6 +126,7 @@ QtObject {
property real controlGap: 5 // TODO different name property real controlGap: 5 // TODO different name
property real splitterMargin: 5 property real splitterMargin: 5
property real splitterThickness: 6
property real twoControlColumnGap: values.controlLabelGap property real twoControlColumnGap: values.controlLabelGap
+ values.controlLabelWidth + values.controlLabelWidth
+ values.controlGap + values.controlGap

View File

@@ -45,7 +45,10 @@ QPixmap MaterialEditorImageProvider::requestPixmap(const QString &id,
pixmap = m_previewPixmap; pixmap = m_previewPixmap;
setRequestedSize(requestedSize); setRequestedSize(requestedSize);
} else { } else {
pixmap = defaultPreview.scaled(requestedSize, Qt::KeepAspectRatio); if (requestedSize.isEmpty())
pixmap = defaultPreview;
else
pixmap = defaultPreview.scaled(requestedSize, Qt::KeepAspectRatio);
} }
} else { } else {
qWarning() << __FUNCTION__ << "Unsupported image id:" << id; qWarning() << __FUNCTION__ << "Unsupported image id:" << id;
@@ -67,7 +70,7 @@ QPixmap MaterialEditorImageProvider::requestPixmap(const QString &id,
*/ */
void MaterialEditorImageProvider::setRequestedSize(const QSize &requestedSize) void MaterialEditorImageProvider::setRequestedSize(const QSize &requestedSize)
{ {
if (!requestedSize.isValid()) if (requestedSize.isEmpty())
return; return;
m_requestedSize = requestedSize; m_requestedSize = requestedSize;