2023-02-09 09:18:39 +01:00
|
|
|
// Copyright (C) 2023 The Qt Company Ltd.
|
2023-01-04 08:52:22 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
import QtQuick
|
2024-01-16 12:30:29 +01:00
|
|
|
import HelperWidgets as HelperWidgets
|
|
|
|
|
import StudioControls as StudioControls
|
|
|
|
|
import StudioTheme as StudioTheme
|
2023-03-09 10:46:32 +01:00
|
|
|
import MaterialBrowserBackend
|
2022-03-18 17:28:28 +02:00
|
|
|
|
|
|
|
|
Item {
|
|
|
|
|
id: root
|
2023-02-16 16:57:34 +02:00
|
|
|
focus: true
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
readonly property real cellWidth: root.thumbnailSize
|
|
|
|
|
readonly property real cellHeight: root.thumbnailSize + 20
|
2022-11-17 17:52:26 +02:00
|
|
|
readonly property bool enableUiElements: materialBrowserModel.hasMaterialLibrary
|
|
|
|
|
&& materialBrowserModel.hasQuick3DImport
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2022-10-18 16:26:16 +03:00
|
|
|
property var currMaterialItem: null
|
2023-03-09 10:46:32 +01:00
|
|
|
property var rootView: MaterialBrowserBackend.rootView
|
|
|
|
|
property var materialBrowserModel: MaterialBrowserBackend.materialBrowserModel
|
|
|
|
|
property var materialBrowserTexturesModel: MaterialBrowserBackend.materialBrowserTexturesModel
|
2022-08-12 11:47:36 +03:00
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
property int numColumns: 0
|
|
|
|
|
property real thumbnailSize: 100
|
|
|
|
|
|
|
|
|
|
readonly property int minThumbSize: 100
|
|
|
|
|
readonly property int maxThumbSize: 150
|
|
|
|
|
|
|
|
|
|
function responsiveResize(width: int, height: int) {
|
|
|
|
|
width -= 2 * StudioTheme.Values.sectionPadding
|
|
|
|
|
|
|
|
|
|
let numColumns = Math.floor(width / root.minThumbSize)
|
|
|
|
|
let remainder = width % root.minThumbSize
|
|
|
|
|
let space = (numColumns - 1) * StudioTheme.Values.sectionGridSpacing
|
|
|
|
|
|
|
|
|
|
if (remainder < space)
|
|
|
|
|
numColumns -= 1
|
|
|
|
|
|
|
|
|
|
if (numColumns < 1)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
let maxItems = Math.max(texturesRepeater.count, materialRepeater.count)
|
|
|
|
|
|
|
|
|
|
if (numColumns > maxItems)
|
|
|
|
|
numColumns = maxItems
|
|
|
|
|
|
|
|
|
|
let rest = width - (numColumns * root.minThumbSize)
|
|
|
|
|
- ((numColumns - 1) * StudioTheme.Values.sectionGridSpacing)
|
|
|
|
|
|
|
|
|
|
root.thumbnailSize = Math.min(root.minThumbSize + (rest / numColumns),
|
|
|
|
|
root.maxThumbSize)
|
|
|
|
|
root.numColumns = numColumns
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onWidthChanged: root.responsiveResize(root.width, root.height)
|
|
|
|
|
|
2022-03-18 17:28:28 +02:00
|
|
|
// Called also from C++ to close context menu on focus out
|
2023-10-10 15:25:50 +02:00
|
|
|
function closeContextMenu() {
|
2022-10-12 20:46:17 +03:00
|
|
|
ctxMenu.close()
|
2022-11-17 15:46:11 +02:00
|
|
|
ctxMenuTextures.close()
|
2023-03-28 15:49:22 +03:00
|
|
|
HelperWidgets.Controller.closeContextMenu()
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called from C++ to refresh a preview material after it changes
|
2023-10-10 15:25:50 +02:00
|
|
|
function refreshPreview(idx) {
|
2022-10-26 19:57:41 +03:00
|
|
|
var item = materialRepeater.itemAt(idx);
|
2022-03-18 17:28:28 +02:00
|
|
|
if (item)
|
2023-10-10 15:25:50 +02:00
|
|
|
item.refreshPreview()
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called from C++
|
2023-10-10 15:25:50 +02:00
|
|
|
function clearSearchFilter() {
|
|
|
|
|
searchBox.clear()
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function nextVisibleItem(idx, count, itemModel) {
|
2023-02-10 14:45:43 +02:00
|
|
|
if (count === 0)
|
|
|
|
|
return idx
|
|
|
|
|
|
|
|
|
|
let pos = 0
|
|
|
|
|
let newIdx = idx
|
|
|
|
|
let direction = 1
|
|
|
|
|
if (count < 0)
|
|
|
|
|
direction = -1
|
|
|
|
|
|
|
|
|
|
while (pos !== count) {
|
|
|
|
|
newIdx += direction
|
|
|
|
|
if (newIdx < 0 || newIdx >= itemModel.rowCount())
|
|
|
|
|
return -1
|
|
|
|
|
if (itemModel.isVisible(newIdx))
|
|
|
|
|
pos += direction
|
2023-01-12 21:02:18 +02:00
|
|
|
}
|
2023-02-10 14:45:43 +02:00
|
|
|
|
|
|
|
|
return newIdx
|
2023-01-12 21:02:18 +02:00
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function visibleItemCount(itemModel) {
|
2023-02-10 14:45:43 +02:00
|
|
|
let curIdx = 0
|
|
|
|
|
let count = 0
|
|
|
|
|
|
|
|
|
|
for (; curIdx < itemModel.rowCount(); ++curIdx) {
|
|
|
|
|
if (itemModel.isVisible(curIdx))
|
|
|
|
|
++count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return count
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function rowIndexOfItem(idx, rowSize, itemModel) {
|
2023-02-10 14:45:43 +02:00
|
|
|
if (rowSize === 1)
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
let curIdx = 0
|
|
|
|
|
let count = -1
|
|
|
|
|
|
|
|
|
|
while (curIdx <= idx) {
|
|
|
|
|
if (curIdx >= itemModel.rowCount())
|
|
|
|
|
break
|
|
|
|
|
if (itemModel.isVisible(curIdx))
|
|
|
|
|
++count
|
|
|
|
|
++curIdx
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return count % rowSize
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function selectNextVisibleItem(delta) {
|
2023-02-13 11:20:27 +01:00
|
|
|
if (searchBox.activeFocus)
|
|
|
|
|
return
|
2023-02-10 14:45:43 +02:00
|
|
|
|
|
|
|
|
let targetIdx = -1
|
|
|
|
|
let newTargetIdx = -1
|
|
|
|
|
let origRowIdx = -1
|
|
|
|
|
let rowIdx = -1
|
|
|
|
|
let matSecFocused = rootView.materialSectionFocused && materialsSection.expanded
|
|
|
|
|
let texSecFocused = !rootView.materialSectionFocused && texturesSection.expanded
|
|
|
|
|
|
|
|
|
|
if (delta < 0) {
|
|
|
|
|
if (matSecFocused) {
|
2023-10-10 15:25:50 +02:00
|
|
|
targetIdx = root.nextVisibleItem(materialBrowserModel.selectedIndex,
|
|
|
|
|
delta, materialBrowserModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
if (targetIdx >= 0)
|
|
|
|
|
materialBrowserModel.selectMaterial(targetIdx)
|
|
|
|
|
} else if (texSecFocused) {
|
2023-10-10 15:25:50 +02:00
|
|
|
targetIdx = root.nextVisibleItem(materialBrowserTexturesModel.selectedIndex,
|
|
|
|
|
delta, materialBrowserTexturesModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
if (targetIdx >= 0) {
|
|
|
|
|
materialBrowserTexturesModel.selectTexture(targetIdx)
|
|
|
|
|
} else if (!materialBrowserModel.isEmpty && materialsSection.expanded) {
|
2023-10-10 15:25:50 +02:00
|
|
|
targetIdx = root.nextVisibleItem(materialBrowserModel.rowCount(), -1, materialBrowserModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
if (targetIdx >= 0) {
|
|
|
|
|
if (delta !== -1) {
|
|
|
|
|
// Try to match column when switching between materials/textures
|
2023-10-10 15:25:50 +02:00
|
|
|
origRowIdx = root.rowIndexOfItem(materialBrowserTexturesModel.selectedIndex,
|
|
|
|
|
-delta, materialBrowserTexturesModel)
|
|
|
|
|
if (root.visibleItemCount(materialBrowserModel) > origRowIdx) {
|
|
|
|
|
rowIdx = root.rowIndexOfItem(targetIdx, -delta, materialBrowserModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
if (rowIdx >= origRowIdx) {
|
2023-10-10 15:25:50 +02:00
|
|
|
newTargetIdx = root.nextVisibleItem(targetIdx,
|
|
|
|
|
-(rowIdx - origRowIdx),
|
|
|
|
|
materialBrowserModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
} else {
|
2023-10-10 15:25:50 +02:00
|
|
|
newTargetIdx = root.nextVisibleItem(targetIdx,
|
|
|
|
|
-(-delta - origRowIdx + rowIdx),
|
|
|
|
|
materialBrowserModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
2023-10-10 15:25:50 +02:00
|
|
|
newTargetIdx = root.nextVisibleItem(materialBrowserModel.rowCount(),
|
|
|
|
|
-1, materialBrowserModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
}
|
|
|
|
|
if (newTargetIdx >= 0)
|
|
|
|
|
targetIdx = newTargetIdx
|
|
|
|
|
}
|
|
|
|
|
materialBrowserModel.selectMaterial(targetIdx)
|
2023-02-13 17:39:33 +02:00
|
|
|
rootView.focusMaterialSection(true)
|
2023-02-10 14:45:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (delta > 0) {
|
|
|
|
|
if (matSecFocused) {
|
2023-10-10 15:25:50 +02:00
|
|
|
targetIdx = root.nextVisibleItem(materialBrowserModel.selectedIndex,
|
|
|
|
|
delta, materialBrowserModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
if (targetIdx >= 0) {
|
|
|
|
|
materialBrowserModel.selectMaterial(targetIdx)
|
|
|
|
|
} else if (!materialBrowserTexturesModel.isEmpty && texturesSection.expanded) {
|
2023-10-10 15:25:50 +02:00
|
|
|
targetIdx = root.nextVisibleItem(-1, 1, materialBrowserTexturesModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
if (targetIdx >= 0) {
|
|
|
|
|
if (delta !== 1) {
|
|
|
|
|
// Try to match column when switching between materials/textures
|
2023-10-10 15:25:50 +02:00
|
|
|
origRowIdx = root.rowIndexOfItem(materialBrowserModel.selectedIndex,
|
|
|
|
|
delta, materialBrowserModel)
|
|
|
|
|
if (root.visibleItemCount(materialBrowserTexturesModel) > origRowIdx) {
|
2023-02-10 14:45:43 +02:00
|
|
|
if (origRowIdx > 0) {
|
2023-10-10 15:25:50 +02:00
|
|
|
newTargetIdx = root.nextVisibleItem(targetIdx, origRowIdx,
|
|
|
|
|
materialBrowserTexturesModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
2023-10-10 15:25:50 +02:00
|
|
|
newTargetIdx = root.nextVisibleItem(materialBrowserTexturesModel.rowCount(),
|
|
|
|
|
-1, materialBrowserTexturesModel)
|
2023-02-10 14:45:43 +02:00
|
|
|
}
|
|
|
|
|
if (newTargetIdx >= 0)
|
|
|
|
|
targetIdx = newTargetIdx
|
|
|
|
|
}
|
|
|
|
|
materialBrowserTexturesModel.selectTexture(targetIdx)
|
2023-02-13 17:39:33 +02:00
|
|
|
rootView.focusMaterialSection(false)
|
2023-02-10 14:45:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (texSecFocused) {
|
2023-10-10 15:25:50 +02:00
|
|
|
targetIdx = root.nextVisibleItem(materialBrowserTexturesModel.selectedIndex,
|
|
|
|
|
delta, materialBrowserTexturesModel)
|
2023-01-12 21:02:18 +02:00
|
|
|
if (targetIdx >= 0)
|
|
|
|
|
materialBrowserTexturesModel.selectTexture(targetIdx)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-10 14:45:43 +02:00
|
|
|
Keys.enabled: true
|
2023-10-10 15:25:50 +02:00
|
|
|
Keys.onDownPressed: root.selectNextVisibleItem(gridMaterials.columns)
|
|
|
|
|
Keys.onUpPressed: root.selectNextVisibleItem(-gridMaterials.columns)
|
|
|
|
|
Keys.onLeftPressed: root.selectNextVisibleItem(-1)
|
|
|
|
|
Keys.onRightPressed: root.selectNextVisibleItem(1)
|
2023-02-10 14:45:43 +02:00
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function handleEnterPress() {
|
2023-02-13 11:20:27 +01:00
|
|
|
if (searchBox.activeFocus)
|
|
|
|
|
return
|
2023-02-10 15:59:30 +02:00
|
|
|
|
|
|
|
|
if (!materialBrowserModel.isEmpty && rootView.materialSectionFocused && materialsSection.expanded)
|
|
|
|
|
materialBrowserModel.openMaterialEditor()
|
|
|
|
|
else if (!materialBrowserTexturesModel.isEmpty && !rootView.materialSectionFocused && texturesSection.expanded)
|
|
|
|
|
materialBrowserTexturesModel.openTextureEditor()
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
Keys.onEnterPressed: root.handleEnterPress()
|
|
|
|
|
Keys.onReturnPressed: root.handleEnterPress()
|
2023-02-10 15:59:30 +02:00
|
|
|
|
2022-11-08 13:02:06 +02:00
|
|
|
MouseArea {
|
|
|
|
|
id: focusGrabber
|
2023-02-16 13:57:43 +02:00
|
|
|
y: searchBox.height
|
|
|
|
|
width: parent.width
|
|
|
|
|
height: parent.height - searchBox.height
|
2022-11-08 13:02:06 +02:00
|
|
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
|
|
|
onPressed: (mouse) => {
|
|
|
|
|
forceActiveFocus() // Steal focus from name edit
|
|
|
|
|
mouse.accepted = false
|
|
|
|
|
}
|
|
|
|
|
z: 1
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 17:28:28 +02:00
|
|
|
MouseArea {
|
|
|
|
|
id: rootMouseArea
|
|
|
|
|
|
2023-07-27 12:00:45 +02:00
|
|
|
y: toolbar.height
|
2023-02-13 17:39:33 +02:00
|
|
|
width: parent.width
|
2023-07-27 12:00:45 +02:00
|
|
|
height: parent.height - toolbar.height
|
2022-03-18 17:28:28 +02:00
|
|
|
|
|
|
|
|
acceptedButtons: Qt.RightButton
|
|
|
|
|
|
2022-09-01 15:03:01 +03:00
|
|
|
onClicked: (mouse) => {
|
2022-11-17 17:52:26 +02:00
|
|
|
if (!root.enableUiElements)
|
2023-10-10 15:25:50 +02:00
|
|
|
return
|
2022-10-26 19:57:41 +03:00
|
|
|
|
|
|
|
|
var matsSecBottom = mapFromItem(materialsSection, 0, materialsSection.y).y
|
2023-10-10 15:25:50 +02:00
|
|
|
+ materialsSection.height
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2022-11-17 17:52:26 +02:00
|
|
|
if (mouse.y < matsSecBottom)
|
2022-10-18 16:26:16 +03:00
|
|
|
ctxMenu.popupMenu()
|
2022-11-17 15:46:11 +02:00
|
|
|
else
|
|
|
|
|
ctxMenuTextures.popupMenu()
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function ensureVisible(yPos, itemHeight) {
|
2023-02-13 13:21:13 +02:00
|
|
|
let currentY = contentYBehavior.targetValue && scrollViewAnim.running
|
|
|
|
|
? contentYBehavior.targetValue : scrollView.contentY
|
|
|
|
|
|
|
|
|
|
if (currentY > yPos) {
|
|
|
|
|
if (yPos < itemHeight)
|
2023-02-13 17:39:33 +02:00
|
|
|
scrollView.contentY = 0
|
|
|
|
|
else
|
2023-02-13 13:21:13 +02:00
|
|
|
scrollView.contentY = yPos
|
|
|
|
|
return true
|
|
|
|
|
} else {
|
|
|
|
|
let adjustedY = yPos + itemHeight - scrollView.height + 8
|
|
|
|
|
if (currentY < adjustedY) {
|
|
|
|
|
if (scrollView.contentHeight - scrollView.height < adjustedY )
|
|
|
|
|
scrollView.contentY = scrollView.contentHeight - scrollView.height
|
|
|
|
|
else
|
|
|
|
|
scrollView.contentY = adjustedY
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function ensureSelectedVisible() {
|
2023-02-13 13:21:13 +02:00
|
|
|
if (rootView.materialSectionFocused && materialsSection.expanded && root.currMaterialItem
|
|
|
|
|
&& materialBrowserModel.isVisible(materialBrowserModel.selectedIndex)) {
|
2023-10-10 15:25:50 +02:00
|
|
|
return root.ensureVisible(root.currMaterialItem.mapToItem(scrollView.contentItem, 0, 0).y,
|
|
|
|
|
root.currMaterialItem.height)
|
2023-02-13 13:21:13 +02:00
|
|
|
} else if (!rootView.materialSectionFocused && texturesSection.expanded) {
|
|
|
|
|
let currItem = texturesRepeater.itemAt(materialBrowserTexturesModel.selectedIndex)
|
|
|
|
|
if (currItem && materialBrowserTexturesModel.isVisible(materialBrowserTexturesModel.selectedIndex))
|
2023-10-10 15:25:50 +02:00
|
|
|
return root.ensureVisible(currItem.mapToItem(scrollView.contentItem, 0, 0).y,
|
|
|
|
|
currItem.height)
|
2023-02-13 13:21:13 +02:00
|
|
|
} else {
|
2023-10-10 15:25:50 +02:00
|
|
|
return root.ensureVisible(0, 90)
|
2023-02-13 17:39:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 13:21:13 +02:00
|
|
|
Timer {
|
|
|
|
|
id: ensureTimer
|
|
|
|
|
interval: 20
|
|
|
|
|
repeat: true
|
|
|
|
|
triggeredOnStart: true
|
|
|
|
|
|
|
|
|
|
onTriggered: {
|
|
|
|
|
// Redo until ensuring didn't change things
|
|
|
|
|
if (!root.ensureSelectedVisible()) {
|
2023-10-10 15:25:50 +02:00
|
|
|
ensureTimer.stop()
|
|
|
|
|
ensureTimer.interval = 20
|
|
|
|
|
ensureTimer.triggeredOnStart = true
|
2023-02-13 13:21:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function startDelayedEnsureTimer(delay) {
|
2023-02-13 13:21:13 +02:00
|
|
|
// Ensuring visibility immediately in some cases like before new search results are rendered
|
|
|
|
|
// causes mapToItem return incorrect values, leading to undesirable flicker,
|
|
|
|
|
// so delay ensuring visibility a bit.
|
|
|
|
|
ensureTimer.interval = delay
|
|
|
|
|
ensureTimer.triggeredOnStart = false
|
|
|
|
|
ensureTimer.restart()
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 17:28:28 +02:00
|
|
|
Connections {
|
|
|
|
|
target: materialBrowserModel
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function onSelectedIndexChanged() {
|
2022-03-18 17:28:28 +02:00
|
|
|
// commit rename upon changing selection
|
2022-10-18 16:26:16 +03:00
|
|
|
if (root.currMaterialItem)
|
2023-05-04 19:31:02 +03:00
|
|
|
root.currMaterialItem.forceFinishEditing();
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2022-10-26 19:57:41 +03:00
|
|
|
root.currMaterialItem = materialRepeater.itemAt(materialBrowserModel.selectedIndex);
|
2023-02-13 17:39:33 +02:00
|
|
|
|
2023-02-13 13:21:13 +02:00
|
|
|
ensureTimer.start()
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function onIsEmptyChanged() {
|
2023-02-13 13:21:13 +02:00
|
|
|
ensureTimer.start()
|
2023-02-13 17:39:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Connections {
|
|
|
|
|
target: materialBrowserTexturesModel
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function onSelectedIndexChanged() {
|
2023-02-13 13:21:13 +02:00
|
|
|
ensureTimer.start()
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function onIsEmptyChanged() {
|
2023-02-13 13:21:13 +02:00
|
|
|
ensureTimer.start()
|
2023-02-13 17:39:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Connections {
|
|
|
|
|
target: rootView
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
function onMaterialSectionFocusedChanged() {
|
2023-02-13 13:21:13 +02:00
|
|
|
ensureTimer.start()
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-18 16:26:16 +03:00
|
|
|
MaterialBrowserContextMenu {
|
2022-10-12 20:46:17 +03:00
|
|
|
id: ctxMenu
|
2023-02-20 15:39:42 +02:00
|
|
|
onClosed: {
|
|
|
|
|
if (restoreFocusOnClose)
|
|
|
|
|
scrollView.forceActiveFocus()
|
|
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
|
2022-11-17 15:46:11 +02:00
|
|
|
TextureBrowserContextMenu {
|
|
|
|
|
id: ctxMenuTextures
|
2023-02-20 15:39:42 +02:00
|
|
|
onClosed: {
|
|
|
|
|
scrollView.forceActiveFocus()
|
|
|
|
|
}
|
2022-11-17 15:46:11 +02:00
|
|
|
}
|
|
|
|
|
|
2023-02-21 12:43:21 +01:00
|
|
|
component DoubleButton: Rectangle {
|
|
|
|
|
id: doubleButton
|
|
|
|
|
|
|
|
|
|
signal clicked()
|
|
|
|
|
|
|
|
|
|
property alias icon: iconLabel.text
|
|
|
|
|
property alias tooltip: mouseArea.tooltip
|
|
|
|
|
|
|
|
|
|
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
|
|
|
|
|
|
|
|
|
width: doubleButton.style.squareControlSize.width * 2
|
|
|
|
|
height: doubleButton.style.squareControlSize.height
|
|
|
|
|
radius: StudioTheme.Values.smallRadius
|
|
|
|
|
|
|
|
|
|
Row {
|
|
|
|
|
id: contentRow
|
|
|
|
|
spacing: 0
|
|
|
|
|
|
|
|
|
|
Text {
|
|
|
|
|
id: iconLabel
|
|
|
|
|
width: doubleButton.style.squareControlSize.width
|
|
|
|
|
height: doubleButton.height
|
|
|
|
|
text: StudioTheme.Constants.material_medium
|
|
|
|
|
font.family: StudioTheme.Constants.iconFont.family
|
|
|
|
|
font.pixelSize: doubleButton.style.baseIconFontSize
|
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Text {
|
|
|
|
|
id: plusLabel
|
|
|
|
|
width: doubleButton.style.squareControlSize.width
|
|
|
|
|
height: doubleButton.height
|
|
|
|
|
text: StudioTheme.Constants.add_medium
|
|
|
|
|
font.family: StudioTheme.Constants.iconFont.family
|
|
|
|
|
font.pixelSize: doubleButton.style.baseIconFontSize
|
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HelperWidgets.ToolTipArea {
|
|
|
|
|
id: mouseArea
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: doubleButton.clicked()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
states: [
|
|
|
|
|
State {
|
|
|
|
|
name: "default"
|
|
|
|
|
when: doubleButton.enabled && !mouseArea.containsMouse && !mouseArea.pressed
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: doubleButton
|
|
|
|
|
color: doubleButton.style.background.idle
|
|
|
|
|
border.color: doubleButton.style.border.idle
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: iconLabel
|
|
|
|
|
color: doubleButton.style.icon.idle
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: plusLabel
|
|
|
|
|
color: doubleButton.style.icon.idle
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
State {
|
|
|
|
|
name: "hover"
|
|
|
|
|
when: doubleButton.enabled && mouseArea.containsMouse && !mouseArea.pressed
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: doubleButton
|
|
|
|
|
color: doubleButton.style.background.hover
|
|
|
|
|
border.color: doubleButton.style.border.hover
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: iconLabel
|
|
|
|
|
color: doubleButton.style.icon.hover
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: plusLabel
|
|
|
|
|
color: doubleButton.style.icon.hover
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
State {
|
|
|
|
|
name: "pressed"
|
|
|
|
|
when: doubleButton.enabled && mouseArea.containsMouse && mouseArea.pressed
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: doubleButton
|
|
|
|
|
color: doubleButton.style.interaction
|
|
|
|
|
border.color: doubleButton.style.interaction
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: iconLabel
|
|
|
|
|
color: doubleButton.style.icon.interaction
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: plusLabel
|
|
|
|
|
color: doubleButton.style.icon.interaction
|
|
|
|
|
}
|
|
|
|
|
},
|
2023-02-23 17:54:47 +01:00
|
|
|
State {
|
|
|
|
|
name: "pressedButNotHovered"
|
|
|
|
|
when: doubleButton.enabled && !mouseArea.containsMouse && mouseArea.pressed
|
|
|
|
|
extend: "hover"
|
|
|
|
|
},
|
2023-02-21 12:43:21 +01:00
|
|
|
State {
|
|
|
|
|
name: "disable"
|
|
|
|
|
when: !doubleButton.enabled
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: doubleButton
|
|
|
|
|
color: doubleButton.style.background.disabled
|
|
|
|
|
border.color: doubleButton.style.border.disabled
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: iconLabel
|
|
|
|
|
color: doubleButton.style.icon.disabled
|
|
|
|
|
}
|
|
|
|
|
PropertyChanges {
|
|
|
|
|
target: plusLabel
|
|
|
|
|
color: doubleButton.style.icon.disabled
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 17:28:28 +02:00
|
|
|
Column {
|
|
|
|
|
id: col
|
2023-02-22 13:34:31 +01:00
|
|
|
anchors.fill: parent
|
2022-03-18 17:28:28 +02:00
|
|
|
spacing: 5
|
|
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
Rectangle {
|
2023-07-27 12:00:45 +02:00
|
|
|
id: toolbar
|
2023-02-09 09:18:39 +01:00
|
|
|
width: parent.width
|
|
|
|
|
height: StudioTheme.Values.doubleToolbarHeight
|
|
|
|
|
color: StudioTheme.Values.themeToolbarBackground
|
|
|
|
|
|
|
|
|
|
Column {
|
|
|
|
|
anchors.fill: parent
|
2023-07-27 12:00:45 +02:00
|
|
|
anchors.topMargin: StudioTheme.Values.toolbarVerticalMargin
|
|
|
|
|
anchors.bottomMargin: StudioTheme.Values.toolbarVerticalMargin
|
|
|
|
|
anchors.leftMargin: StudioTheme.Values.toolbarHorizontalMargin
|
|
|
|
|
anchors.rightMargin: StudioTheme.Values.toolbarHorizontalMargin
|
|
|
|
|
spacing: StudioTheme.Values.toolbarColumnSpacing
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
StudioControls.SearchBox {
|
|
|
|
|
id: searchBox
|
2023-02-13 11:20:27 +01:00
|
|
|
width: parent.width
|
2023-02-09 09:18:39 +01:00
|
|
|
style: StudioTheme.Values.searchControlStyle
|
|
|
|
|
|
2023-02-13 13:21:13 +02:00
|
|
|
property string previousSearchText: ""
|
|
|
|
|
property bool materialsExpanded: true
|
|
|
|
|
property bool texturesExpanded: true
|
|
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
onSearchChanged: (searchText) => {
|
2023-02-13 13:21:13 +02:00
|
|
|
if (searchText !== "") {
|
|
|
|
|
if (previousSearchText === "") {
|
|
|
|
|
materialsExpanded = materialsSection.expanded
|
|
|
|
|
texturesExpanded = texturesSection.expanded
|
|
|
|
|
}
|
|
|
|
|
materialsSection.expanded = true
|
|
|
|
|
texturesSection.expanded = true
|
|
|
|
|
} else if (previousSearchText !== "") {
|
|
|
|
|
materialsSection.expanded = materialsExpanded
|
|
|
|
|
texturesSection.expanded = texturesExpanded
|
|
|
|
|
}
|
|
|
|
|
previousSearchText = searchText
|
|
|
|
|
|
|
|
|
|
root.startDelayedEnsureTimer(50)
|
|
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
rootView.handleSearchFilterChanged(searchText)
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
Row {
|
2023-02-13 11:20:27 +01:00
|
|
|
width: parent.width
|
2023-02-09 09:18:39 +01:00
|
|
|
height: StudioTheme.Values.toolbarHeight
|
|
|
|
|
spacing: 6
|
|
|
|
|
|
2023-02-21 12:43:21 +01:00
|
|
|
DoubleButton {
|
2023-02-09 09:18:39 +01:00
|
|
|
id: addMaterial
|
2023-02-21 12:43:21 +01:00
|
|
|
icon: StudioTheme.Constants.material_medium
|
2023-02-09 09:18:39 +01:00
|
|
|
tooltip: qsTr("Add a Material.")
|
|
|
|
|
onClicked: materialBrowserModel.addNewMaterial()
|
|
|
|
|
enabled: root.enableUiElements
|
|
|
|
|
}
|
2022-09-26 15:21:33 +03:00
|
|
|
|
2023-02-21 12:43:21 +01:00
|
|
|
DoubleButton {
|
2023-02-09 09:18:39 +01:00
|
|
|
id: addTexture
|
2023-02-21 12:43:21 +01:00
|
|
|
icon: StudioTheme.Constants.textures_medium
|
2023-02-09 09:18:39 +01:00
|
|
|
tooltip: qsTr("Add a Texture.")
|
|
|
|
|
onClicked: materialBrowserTexturesModel.addNewTexture()
|
|
|
|
|
enabled: root.enableUiElements
|
|
|
|
|
}
|
2022-10-03 15:07:43 +03:00
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-27 12:00:45 +02:00
|
|
|
Item {
|
2022-03-18 17:28:28 +02:00
|
|
|
width: root.width
|
2023-07-27 12:00:45 +02:00
|
|
|
height: root.height - toolbar.height
|
|
|
|
|
visible: hint.text !== ""
|
|
|
|
|
|
|
|
|
|
Text {
|
|
|
|
|
id: hint
|
|
|
|
|
width: parent.width - 40
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
|
|
|
|
|
text: {
|
2023-09-14 17:08:56 +03:00
|
|
|
if (!materialBrowserModel.isQt6Project)
|
|
|
|
|
qsTr("<b>Material Browser</b> is not supported in Qt5 projects.")
|
|
|
|
|
else if (!materialBrowserModel.hasQuick3DImport)
|
2023-07-27 12:00:45 +02:00
|
|
|
qsTr("To use <b>Material Browser</b>, first add the QtQuick3D module in the <b>Components</b> view.")
|
|
|
|
|
else if (!materialBrowserModel.hasMaterialLibrary)
|
|
|
|
|
qsTr("<b>Material Browser</b> is disabled inside a non-visual component.")
|
|
|
|
|
else
|
|
|
|
|
""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
textFormat: Text.RichText
|
|
|
|
|
color: StudioTheme.Values.themeTextColor
|
|
|
|
|
font.pixelSize: StudioTheme.Values.mediumFontSize
|
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
|
wrapMode: Text.WordWrap
|
|
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
HelperWidgets.ScrollView {
|
2022-03-18 17:28:28 +02:00
|
|
|
id: scrollView
|
|
|
|
|
|
|
|
|
|
width: root.width
|
2023-10-10 15:25:50 +02:00
|
|
|
height: root.height - toolbar.height - col.spacing
|
2022-03-18 17:28:28 +02:00
|
|
|
clip: true
|
2022-11-17 17:52:26 +02:00
|
|
|
visible: root.enableUiElements
|
2023-10-10 15:25:50 +02:00
|
|
|
hideHorizontalScrollBar: true
|
2023-02-07 10:42:22 +02:00
|
|
|
interactive: !ctxMenu.opened && !ctxMenuTextures.opened && !rootView.isDragging
|
2023-04-04 14:31:35 +03:00
|
|
|
&& !HelperWidgets.Controller.contextMenuOpened
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2023-02-13 17:39:33 +02:00
|
|
|
Behavior on contentY {
|
2023-02-13 13:21:13 +02:00
|
|
|
id: contentYBehavior
|
|
|
|
|
PropertyAnimation {
|
|
|
|
|
id: scrollViewAnim
|
|
|
|
|
easing.type: Easing.InOutQuad
|
|
|
|
|
}
|
2023-02-13 17:39:33 +02:00
|
|
|
}
|
|
|
|
|
|
2022-09-01 15:03:01 +03:00
|
|
|
Column {
|
2022-11-21 14:17:00 +02:00
|
|
|
Item {
|
2022-09-01 15:03:01 +03:00
|
|
|
width: root.width
|
2022-11-21 14:17:00 +02:00
|
|
|
height: materialsSection.height
|
2022-10-20 17:42:46 +03:00
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
HelperWidgets.Section {
|
2022-11-21 14:17:00 +02:00
|
|
|
id: materialsSection
|
2022-10-20 17:42:46 +03:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
width: root.width
|
2023-10-10 15:25:50 +02:00
|
|
|
|
|
|
|
|
leftPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
rightPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
topPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
bottomPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
caption: qsTr("Materials")
|
|
|
|
|
dropEnabled: true
|
2023-03-09 15:46:42 +02:00
|
|
|
category: "MaterialBrowser"
|
2022-10-20 17:42:46 +03:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
onDropEnter: (drag) => {
|
|
|
|
|
drag.accepted = drag.formats[0] === "application/vnd.qtdesignstudio.bundlematerial"
|
|
|
|
|
materialsSection.highlight = drag.accepted
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onDropExit: {
|
|
|
|
|
materialsSection.highlight = false
|
|
|
|
|
}
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2023-02-17 15:22:55 +02:00
|
|
|
onDrop: (drag) => {
|
|
|
|
|
drag.accept()
|
2022-11-21 14:17:00 +02:00
|
|
|
materialsSection.highlight = false
|
|
|
|
|
rootView.acceptBundleMaterialDrop()
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 13:21:13 +02:00
|
|
|
onExpandedChanged: {
|
2023-02-20 15:39:42 +02:00
|
|
|
if (expanded) {
|
|
|
|
|
if (root.visibleItemCount(materialBrowserModel) > 0)
|
|
|
|
|
rootView.focusMaterialSection(true)
|
2023-02-24 15:41:00 +02:00
|
|
|
if (!searchBox.activeFocus)
|
|
|
|
|
scrollView.forceActiveFocus()
|
2023-02-20 15:39:42 +02:00
|
|
|
} else {
|
2023-02-13 13:21:13 +02:00
|
|
|
root.startDelayedEnsureTimer(300) // wait for section collapse animation
|
|
|
|
|
rootView.focusMaterialSection(false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
Grid {
|
2023-01-12 21:02:18 +02:00
|
|
|
id: gridMaterials
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
width: scrollView.width - materialsSection.leftPadding
|
|
|
|
|
- materialsSection.rightPadding
|
|
|
|
|
spacing: StudioTheme.Values.sectionGridSpacing
|
|
|
|
|
columns: root.numColumns
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
Repeater {
|
|
|
|
|
id: materialRepeater
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
model: materialBrowserModel
|
2023-01-23 14:22:42 +02:00
|
|
|
|
|
|
|
|
onItemRemoved: (index, item) => {
|
|
|
|
|
if (item === root.currMaterialItem)
|
|
|
|
|
root.currMaterialItem = null
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
delegate: MaterialItem {
|
|
|
|
|
width: root.cellWidth
|
|
|
|
|
height: root.cellHeight
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
onShowContextMenu: ctxMenu.popupMenu(this, model)
|
2022-09-01 15:03:01 +03:00
|
|
|
}
|
2023-10-10 15:25:50 +02:00
|
|
|
|
|
|
|
|
onCountChanged: root.responsiveResize(root.width, root.height)
|
2022-09-01 15:03:01 +03:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
Text {
|
|
|
|
|
text: qsTr("No match found.");
|
|
|
|
|
color: StudioTheme.Values.themeTextColor
|
|
|
|
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
|
|
|
|
leftPadding: 10
|
2022-11-29 19:35:10 +02:00
|
|
|
visible: materialBrowserModel.isEmpty && !searchBox.isEmpty()
|
2022-11-21 14:17:00 +02:00
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
Text {
|
|
|
|
|
text:qsTr("There are no materials in this project.<br>Select '<b>+</b>' to create one.")
|
|
|
|
|
visible: materialBrowserModel.isEmpty && searchBox.isEmpty()
|
|
|
|
|
textFormat: Text.RichText
|
|
|
|
|
color: StudioTheme.Values.themeTextColor
|
|
|
|
|
font.pixelSize: StudioTheme.Values.mediumFontSize
|
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
|
wrapMode: Text.WordWrap
|
|
|
|
|
width: root.width
|
|
|
|
|
}
|
2022-09-01 15:03:01 +03:00
|
|
|
}
|
2022-11-21 14:17:00 +02:00
|
|
|
}
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
Item {
|
|
|
|
|
width: root.width
|
|
|
|
|
height: texturesSection.height
|
2022-10-26 19:57:41 +03:00
|
|
|
|
2023-02-09 09:18:39 +01:00
|
|
|
HelperWidgets.Section {
|
2022-11-21 14:17:00 +02:00
|
|
|
id: texturesSection
|
2022-10-26 19:57:41 +03:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
width: root.width
|
2023-10-10 15:25:50 +02:00
|
|
|
leftPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
rightPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
topPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
bottomPadding: StudioTheme.Values.sectionPadding
|
|
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
caption: qsTr("Textures")
|
2023-03-09 15:46:42 +02:00
|
|
|
category: "MaterialBrowser"
|
2022-11-21 14:17:00 +02:00
|
|
|
|
2022-11-22 17:09:31 +02:00
|
|
|
dropEnabled: true
|
|
|
|
|
|
|
|
|
|
onDropEnter: (drag) => {
|
2023-03-06 17:27:25 +02:00
|
|
|
let accepted = drag.formats[0] === "application/vnd.qtdesignstudio.bundletexture"
|
|
|
|
|
if (drag.formats[0] === "application/vnd.qtdesignstudio.assets")
|
|
|
|
|
accepted = rootView.hasAcceptableAssets(drag.urls)
|
|
|
|
|
drag.accepted = accepted
|
2022-11-22 17:09:31 +02:00
|
|
|
highlight = drag.accepted
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onDropExit: {
|
|
|
|
|
highlight = false
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-17 15:22:55 +02:00
|
|
|
onDrop: (drag) => {
|
|
|
|
|
drag.accept()
|
2022-11-22 17:09:31 +02:00
|
|
|
highlight = false
|
2023-02-01 12:10:34 +02:00
|
|
|
if (drag.formats[0] === "application/vnd.qtdesignstudio.bundletexture")
|
|
|
|
|
rootView.acceptBundleTextureDrop()
|
|
|
|
|
else if (drag.formats[0] === "application/vnd.qtdesignstudio.assets")
|
|
|
|
|
rootView.acceptAssetsDrop(drag.urls)
|
2022-11-22 17:09:31 +02:00
|
|
|
}
|
|
|
|
|
|
2023-02-13 13:21:13 +02:00
|
|
|
onExpandedChanged: {
|
2023-02-20 15:39:42 +02:00
|
|
|
if (expanded) {
|
|
|
|
|
if (root.visibleItemCount(materialBrowserTexturesModel) > 0)
|
|
|
|
|
rootView.focusMaterialSection(false)
|
2023-02-24 15:41:00 +02:00
|
|
|
if (!searchBox.activeFocus)
|
|
|
|
|
scrollView.forceActiveFocus()
|
2023-02-20 15:39:42 +02:00
|
|
|
} else {
|
2023-02-13 13:21:13 +02:00
|
|
|
root.startDelayedEnsureTimer(300) // wait for section collapse animation
|
|
|
|
|
rootView.focusMaterialSection(true)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
Grid {
|
2023-01-12 21:02:18 +02:00
|
|
|
id: gridTextures
|
|
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
width: scrollView.width - texturesSection.leftPadding
|
|
|
|
|
- texturesSection.rightPadding
|
|
|
|
|
spacing: StudioTheme.Values.sectionGridSpacing
|
|
|
|
|
columns: root.numColumns
|
2022-11-21 14:17:00 +02:00
|
|
|
|
|
|
|
|
Repeater {
|
|
|
|
|
id: texturesRepeater
|
|
|
|
|
|
|
|
|
|
model: materialBrowserTexturesModel
|
|
|
|
|
delegate: TextureItem {
|
|
|
|
|
width: root.cellWidth
|
2023-05-04 19:31:02 +03:00
|
|
|
height: root.cellHeight
|
2022-11-21 14:17:00 +02:00
|
|
|
|
2023-10-10 15:25:50 +02:00
|
|
|
onShowContextMenu: ctxMenuTextures.popupMenu(model)
|
2022-09-01 15:03:01 +03:00
|
|
|
}
|
2023-10-10 15:25:50 +02:00
|
|
|
|
|
|
|
|
onCountChanged: root.responsiveResize(root.width, root.height)
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
2022-09-01 15:03:01 +03:00
|
|
|
|
2022-11-21 14:17:00 +02:00
|
|
|
Text {
|
|
|
|
|
text: qsTr("No match found.");
|
|
|
|
|
color: StudioTheme.Values.themeTextColor
|
|
|
|
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
|
|
|
|
leftPadding: 10
|
2022-11-29 19:35:10 +02:00
|
|
|
visible: materialBrowserTexturesModel.isEmpty && !searchBox.isEmpty()
|
2022-11-21 14:17:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Text {
|
2022-11-24 15:30:33 +02:00
|
|
|
text:qsTr("There are no textures in this project.")
|
2022-11-21 14:17:00 +02:00
|
|
|
visible: materialBrowserTexturesModel.isEmpty && searchBox.isEmpty()
|
|
|
|
|
textFormat: Text.RichText
|
|
|
|
|
color: StudioTheme.Values.themeTextColor
|
|
|
|
|
font.pixelSize: StudioTheme.Values.mediumFontSize
|
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
|
wrapMode: Text.WordWrap
|
|
|
|
|
width: root.width
|
|
|
|
|
}
|
2022-10-26 19:57:41 +03:00
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
2022-11-22 17:09:31 +02:00
|
|
|
|
|
|
|
|
DropArea {
|
|
|
|
|
id: masterDropArea
|
|
|
|
|
|
|
|
|
|
property int emptyHeight: scrollView.height - materialsSection.height - texturesSection.height
|
|
|
|
|
|
|
|
|
|
width: root.width
|
|
|
|
|
height: emptyHeight > 0 ? emptyHeight : 0
|
|
|
|
|
|
|
|
|
|
enabled: true
|
|
|
|
|
|
|
|
|
|
onEntered: (drag) => texturesSection.dropEnter(drag)
|
|
|
|
|
onDropped: (drag) => texturesSection.drop(drag)
|
|
|
|
|
onExited: texturesSection.dropExit()
|
|
|
|
|
}
|
2022-03-18 17:28:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|