forked from qt-creator/qt-creator
QmlDesigner: Make MaterialEditor FullScreen
Task-number: QDS-12368 Change-Id: Ia65ca2cb5c89507b5290a32f1829551cec236192 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -2,12 +2,17 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtCore
|
||||
import HelperWidgets
|
||||
import StudioControls 1.0 as StudioControls
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string __previewEnv
|
||||
property string __previewModel
|
||||
|
||||
width: 420
|
||||
height: 420
|
||||
|
||||
@@ -16,23 +21,18 @@ Item {
|
||||
signal previewModelChanged(string model)
|
||||
|
||||
// invoked from C++ to refresh material preview image
|
||||
function refreshPreview()
|
||||
{
|
||||
itemPane.headerItem.refreshPreview()
|
||||
}
|
||||
signal refreshPreview()
|
||||
|
||||
// Called from C++ to close context menu on focus out
|
||||
function closeContextMenu()
|
||||
{
|
||||
itemPane.headerItem.closeContextMenu()
|
||||
Controller.closeContextMenu()
|
||||
}
|
||||
|
||||
// Called from C++ to initialize preview menu checkmarks
|
||||
function initPreviewData(env, model)
|
||||
{
|
||||
itemPane.headerItem.previewEnv = env
|
||||
itemPane.headerItem.previewModel = model
|
||||
function initPreviewData(env, model) {
|
||||
root.__previewEnv = env
|
||||
root.__previewModel = model
|
||||
}
|
||||
|
||||
MaterialEditorToolBar {
|
||||
@@ -47,56 +47,105 @@ Item {
|
||||
id: settings
|
||||
|
||||
property var topSection
|
||||
property bool dockMode
|
||||
}
|
||||
|
||||
PropertyEditorPane {
|
||||
id: itemPane
|
||||
StudioControls.SplitView {
|
||||
id: splitView
|
||||
|
||||
readonly property bool isHorizontal: splitView.orientation == Qt.Horizontal
|
||||
|
||||
anchors.top: toolbar.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
|
||||
orientation: splitView.width > 1000 ? Qt.Horizontal : Qt.Vertical
|
||||
clip: true
|
||||
|
||||
headerComponent: MaterialEditorTopSection {
|
||||
id: topSection
|
||||
onPreviewEnvChanged: root.previewEnvChanged(previewEnv)
|
||||
onPreviewModelChanged: root.previewModelChanged(previewModel)
|
||||
|
||||
Component.onCompleted: topSection.restoreState(settings.topSection)
|
||||
Component.onDestruction: settings.topSection = topSection.saveState()
|
||||
}
|
||||
|
||||
DynamicPropertiesSection {
|
||||
propertiesModel: MaterialEditorDynamicPropertiesModel {}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: specificsTwo
|
||||
id: leftSideView
|
||||
|
||||
property string theSource: specificQmlData
|
||||
SplitView.fillWidth: leftSideView.visible
|
||||
SplitView.fillHeight: leftSideView.visible
|
||||
SplitView.minimumWidth: leftSideView.visible ? 300 : 0
|
||||
SplitView.minimumHeight: leftSideView.visible ? 300 : 0
|
||||
|
||||
width: parent.width
|
||||
visible: specificsTwo.theSource !== ""
|
||||
sourceComponent: specificQmlComponent
|
||||
active: splitView.isHorizontal
|
||||
visible: leftSideView.active && leftSideView.item
|
||||
|
||||
onTheSourceChanged: {
|
||||
specificsTwo.active = false
|
||||
specificsTwo.active = true
|
||||
sourceComponent: PreviewComponent {}
|
||||
}
|
||||
|
||||
PropertyEditorPane {
|
||||
id: itemPane
|
||||
|
||||
clip: true
|
||||
SplitView.fillWidth: !leftSideView.visible
|
||||
SplitView.fillHeight: true
|
||||
SplitView.minimumWidth: leftSideView.visible ? 400 : 0
|
||||
SplitView.maximumWidth: leftSideView.visible ? 800 : -1
|
||||
|
||||
headerDocked: !leftSideView.visible && settings.dockMode
|
||||
|
||||
headerComponent: MaterialEditorTopSection {
|
||||
id: topSection
|
||||
|
||||
Component.onCompleted: topSection.restoreState(settings.topSection)
|
||||
Component.onDestruction: settings.topSection = topSection.saveState()
|
||||
previewComponent: PreviewComponent {}
|
||||
showImage: !splitView.isHorizontal
|
||||
}
|
||||
|
||||
DynamicPropertiesSection {
|
||||
propertiesModel: MaterialEditorDynamicPropertiesModel {}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: specificsTwo
|
||||
|
||||
property string theSource: specificQmlData
|
||||
|
||||
width: itemPane.width
|
||||
visible: specificsTwo.theSource !== ""
|
||||
sourceComponent: specificQmlComponent
|
||||
|
||||
onTheSourceChanged: {
|
||||
specificsTwo.active = false
|
||||
specificsTwo.active = true
|
||||
}
|
||||
}
|
||||
|
||||
Item { // spacer
|
||||
width: 1
|
||||
height: 10
|
||||
visible: specificsTwo.visible
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: specificsOne
|
||||
width: itemPane.width
|
||||
source: specificsUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item { // spacer
|
||||
width: 1
|
||||
height: 10
|
||||
visible: specificsTwo.visible
|
||||
}
|
||||
component PreviewComponent : MaterialEditorPreview {
|
||||
id: previewItem
|
||||
|
||||
Loader {
|
||||
id: specificsOne
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
source: specificsUrl
|
||||
onPreviewEnvChanged: root.previewEnvChanged(previewEnv)
|
||||
onPreviewModelChanged: root.previewModelChanged(previewModel)
|
||||
|
||||
previewEnv: root.__previewEnv
|
||||
previewModel: root.__previewModel
|
||||
pinned: settings.dockMode
|
||||
showPinButton: !leftSideView.visible
|
||||
onPinnedChanged: settings.dockMode = previewItem.pinned
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
|
||||
function onRefreshPreview() {
|
||||
previewItem.refreshPreview()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,185 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import HelperWidgets as HelperWidgets
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property string previewEnv
|
||||
property string previewModel
|
||||
property alias pinned: pinButton.checked
|
||||
property alias showPinButton: pinButton.visible
|
||||
|
||||
property StudioTheme.ControlStyle buttonStyle: StudioTheme.ViewBarButtonStyle {
|
||||
// This is how you can override stuff from the control styles
|
||||
baseIconFontSize: StudioTheme.Values.bigIconFontSize
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: HelperWidgets.Controller
|
||||
|
||||
function onCloseContextMenu() {
|
||||
root.closeContextMenu()
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: image.height
|
||||
|
||||
clip: true
|
||||
color: "#000000"
|
||||
|
||||
// Called from C++ to close context menu on focus out
|
||||
function closeContextMenu()
|
||||
{
|
||||
modelMenu.close()
|
||||
envMenu.close()
|
||||
}
|
||||
|
||||
function refreshPreview()
|
||||
{
|
||||
image.source = ""
|
||||
image.source = "image://materialEditor/preview"
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
|
||||
source: "image://materialEditor/preview"
|
||||
cache: false
|
||||
smooth: true
|
||||
|
||||
sourceSize.width: image.width
|
||||
sourceSize.height: image.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: 5
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: optionsToolbar.spacing
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
id: pinButton
|
||||
|
||||
style: root.buttonStyle
|
||||
buttonIcon: pinButton.checked ? StudioTheme.Constants.pin : StudioTheme.Constants.unpin
|
||||
checkable: true
|
||||
}
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
id: previewEnvMenuButton
|
||||
|
||||
style: root.buttonStyle
|
||||
buttonIcon: StudioTheme.Constants.textures_medium
|
||||
tooltip: qsTr("Select preview environment.")
|
||||
onClicked: envMenu.popup()
|
||||
}
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
id: previewModelMenuButton
|
||||
|
||||
style: root.buttonStyle
|
||||
buttonIcon: StudioTheme.Constants.cube_medium
|
||||
tooltip: qsTr("Select preview model.")
|
||||
onClicked: modelMenu.popup()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StudioControls.Menu {
|
||||
id: modelMenu
|
||||
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||
|
||||
ListModel {
|
||||
id: modelMenuModel
|
||||
ListElement {
|
||||
modelName: qsTr("Cone")
|
||||
modelStr: "#Cone"
|
||||
}
|
||||
ListElement {
|
||||
modelName: qsTr("Cube")
|
||||
modelStr: "#Cube"
|
||||
}
|
||||
ListElement {
|
||||
modelName: qsTr("Cylinder")
|
||||
modelStr: "#Cylinder"
|
||||
}
|
||||
ListElement {
|
||||
modelName: qsTr("Sphere")
|
||||
modelStr: "#Sphere"
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: modelMenuModel
|
||||
StudioControls.MenuItemWithIcon {
|
||||
text: modelName
|
||||
onClicked: {
|
||||
// Force property change notifications to keep check mark when reselected
|
||||
root.previewModel = ""
|
||||
root.previewModel = modelStr
|
||||
}
|
||||
checkable: true
|
||||
checked: root.previewModel === modelStr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StudioControls.Menu {
|
||||
id: envMenu
|
||||
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||
|
||||
ListModel {
|
||||
id: envMenuModel
|
||||
ListElement {
|
||||
envName: qsTr("Basic")
|
||||
envStr: "Basic"
|
||||
}
|
||||
ListElement {
|
||||
envName: qsTr("Color")
|
||||
envStr: "Color"
|
||||
}
|
||||
ListElement {
|
||||
envName: qsTr("Studio")
|
||||
envStr: "SkyBox=preview_studio"
|
||||
}
|
||||
ListElement {
|
||||
envName: qsTr("Landscape")
|
||||
envStr: "SkyBox=preview_landscape"
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: envMenuModel
|
||||
StudioControls.MenuItemWithIcon {
|
||||
text: envName
|
||||
onClicked: {
|
||||
// Force property change notifications to keep check mark when reselected
|
||||
root.previewEnv = ""
|
||||
root.previewEnv = envStr
|
||||
}
|
||||
checkable: true
|
||||
checked: root.previewEnv === envStr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,201 +8,29 @@ import HelperWidgets as HelperWidgets
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
SplitView {
|
||||
StudioControls.SplitView {
|
||||
id: root
|
||||
|
||||
property string previewEnv
|
||||
property string previewModel
|
||||
property alias showImage: previewLoader.active
|
||||
property Component previewComponent: null
|
||||
|
||||
property real __spacing: 5
|
||||
|
||||
property StudioTheme.ControlStyle buttonStyle: StudioTheme.ViewBarButtonStyle {
|
||||
//This is how you can override stuff from the control styles
|
||||
baseIconFontSize: StudioTheme.Values.bigIconFontSize
|
||||
}
|
||||
|
||||
function refreshPreview()
|
||||
{
|
||||
materialPreview.source = ""
|
||||
materialPreview.source = "image://materialEditor/preview"
|
||||
}
|
||||
|
||||
// Called from C++ to close context menu on focus out
|
||||
function closeContextMenu()
|
||||
{
|
||||
modelMenu.close()
|
||||
envMenu.close()
|
||||
}
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
implicitHeight: previewRect.implicitHeight + nameSection.implicitHeight
|
||||
width: parent.width
|
||||
implicitHeight: showImage ? previewLoader.implicitHeight + nameSection.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 {
|
||||
id: modelMenu
|
||||
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||
|
||||
ListModel {
|
||||
id: modelMenuModel
|
||||
ListElement {
|
||||
modelName: qsTr("Cone")
|
||||
modelStr: "#Cone"
|
||||
}
|
||||
ListElement {
|
||||
modelName: qsTr("Cube")
|
||||
modelStr: "#Cube"
|
||||
}
|
||||
ListElement {
|
||||
modelName: qsTr("Cylinder")
|
||||
modelStr: "#Cylinder"
|
||||
}
|
||||
ListElement {
|
||||
modelName: qsTr("Sphere")
|
||||
modelStr: "#Sphere"
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: modelMenuModel
|
||||
StudioControls.MenuItemWithIcon {
|
||||
text: modelName
|
||||
onClicked: {
|
||||
// Force property change notifications to keep check mark when reselected
|
||||
root.previewModel = ""
|
||||
root.previewModel = modelStr
|
||||
}
|
||||
checkable: true
|
||||
checked: root.previewModel === modelStr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StudioControls.Menu {
|
||||
id: envMenu
|
||||
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||
|
||||
ListModel {
|
||||
id: envMenuModel
|
||||
ListElement {
|
||||
envName: qsTr("Basic")
|
||||
envStr: "Basic"
|
||||
}
|
||||
ListElement {
|
||||
envName: qsTr("Color")
|
||||
envStr: "Color"
|
||||
}
|
||||
ListElement {
|
||||
envName: qsTr("Studio")
|
||||
envStr: "SkyBox=preview_studio"
|
||||
}
|
||||
ListElement {
|
||||
envName: qsTr("Landscape")
|
||||
envStr: "SkyBox=preview_landscape"
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: envMenuModel
|
||||
StudioControls.MenuItemWithIcon {
|
||||
text: envName
|
||||
onClicked: {
|
||||
// Force property change notifications to keep check mark when reselected
|
||||
root.previewEnv = ""
|
||||
root.previewEnv = envStr
|
||||
}
|
||||
checkable: true
|
||||
checked: root.previewEnv === envStr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: previewRect
|
||||
Loader {
|
||||
id: previewLoader
|
||||
|
||||
SplitView.fillWidth: true
|
||||
SplitView.minimumWidth: 152
|
||||
SplitView.preferredHeight: Math.min(root.width * 0.75, 400)
|
||||
SplitView.minimumHeight: 150
|
||||
implicitHeight: materialPreview.height
|
||||
SplitView.preferredHeight: previewLoader.visible ? Math.min(root.width * 0.75, 400) : 0
|
||||
SplitView.minimumHeight: previewLoader.visible ? 150 : 0
|
||||
SplitView.maximumHeight: previewLoader.visible ? 600 : 0
|
||||
|
||||
clip: true
|
||||
color: "#000000"
|
||||
visible: previewLoader.active && previewLoader.item
|
||||
|
||||
Image {
|
||||
id: materialPreview
|
||||
|
||||
width: root.width
|
||||
height: previewRect.height
|
||||
anchors.centerIn: parent
|
||||
|
||||
fillMode: Image.PreserveAspectFit
|
||||
|
||||
source: "image://materialEditor/preview"
|
||||
cache: false
|
||||
smooth: true
|
||||
|
||||
sourceSize.width: materialPreview.width
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sourceComponent: root.previewComponent
|
||||
}
|
||||
|
||||
HelperWidgets.Section {
|
||||
|
@@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QuickControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
QuickControls.SplitView {
|
||||
id: control
|
||||
|
||||
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
|
||||
|
||||
handle: Rectangle {
|
||||
implicitWidth: control.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : control.width
|
||||
implicitHeight: control.orientation === Qt.Horizontal ? control.height : StudioTheme.Values.splitterThickness
|
||||
color: QuickControls.SplitHandle.pressed ? control.style.slider.handleInteraction
|
||||
: (QuickControls.SplitHandle.hovered ? control.style.slider.handleHover
|
||||
: "transparent")
|
||||
}
|
||||
}
|
@@ -51,6 +51,7 @@ SortFilterModel 1.0 SortFilterModel.qml
|
||||
SpinBox 1.0 SpinBox.qml
|
||||
SpinBoxIndicator 1.0 SpinBoxIndicator.qml
|
||||
SpinBoxInput 1.0 SpinBoxInput.qml
|
||||
SplitView 1.0 SplitView.qml
|
||||
Switch 1.0 Switch.qml
|
||||
TabBar 1.0 TabBar.qml
|
||||
TabButton 1.0 TabButton.qml
|
||||
|
@@ -863,10 +863,13 @@ void MaterialEditorView::propertiesAboutToBeRemoved(const QList<AbstractProperty
|
||||
void MaterialEditorView::requestPreviewRender()
|
||||
{
|
||||
if (model() && model()->nodeInstanceView() && m_selectedMaterial.isValid()) {
|
||||
static int requestId = 0;
|
||||
m_previewRequestId = QByteArray(MATERIAL_EDITOR_IMAGE_REQUEST_ID)
|
||||
+ QByteArray::number(++requestId);
|
||||
model()->nodeInstanceView()->previewImageDataForGenericNode(m_selectedMaterial,
|
||||
{},
|
||||
m_previewSize,
|
||||
MATERIAL_EDITOR_IMAGE_REQUEST_ID);
|
||||
m_previewRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -955,11 +958,10 @@ void MaterialEditorView::modelNodePreviewPixmapChanged(const ModelNode &node,
|
||||
const QPixmap &pixmap,
|
||||
const QByteArray &requestId)
|
||||
{
|
||||
if (node != m_selectedMaterial)
|
||||
if (node != m_selectedMaterial || requestId != m_previewRequestId)
|
||||
return;
|
||||
|
||||
if (requestId == MATERIAL_EDITOR_IMAGE_REQUEST_ID)
|
||||
m_qmlBackEnd->updateMaterialPreview(pixmap);
|
||||
m_qmlBackEnd->updateMaterialPreview(pixmap);
|
||||
}
|
||||
|
||||
void MaterialEditorView::importsChanged([[maybe_unused]] const Imports &addedImports,
|
||||
|
@@ -129,6 +129,7 @@ private:
|
||||
bool m_hasMaterialRoot = false;
|
||||
bool m_initializingPreviewData = false;
|
||||
QSize m_previewSize;
|
||||
QByteArray m_previewRequestId;
|
||||
|
||||
QPointer<QColorDialog> m_colorDialog;
|
||||
QPointer<ItemLibraryInfo> m_itemLibraryInfo;
|
||||
|
Reference in New Issue
Block a user