Merge pull request #13975 from Ultimaker/CURA-9622_unable_to_scroll_long_materials_list

[CURA-9522] Materials list goes off screen.
This commit is contained in:
Remco Burema 2022-12-27 12:34:03 +01:00 committed by GitHub
commit 0cdfa3477b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 163 additions and 79 deletions

View File

@ -17,6 +17,12 @@ UM.MainWindow
{
id: base
Item
{
id: mainWindow
anchors.fill: parent
}
// Cura application window title
title:
{

View File

@ -1,4 +1,4 @@
// Copyright (c) 2022 Ultimaker B.V.
// Copyright (c) 2022 UltiMaker
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
@ -36,6 +36,7 @@ Cura.MenuItem
UM.Label
{
id: brandLabelText
text: replaceText(materialBrandMenu.text)
Layout.fillWidth: true
Layout.fillHeight:true
@ -84,33 +85,15 @@ Cura.MenuItem
onTriggered: menuPopup.close()
}
Popup
MaterialBrandSubMenu
{
id: menuPopup
width: materialTypesList.width + padding * 2
height: materialTypesList.height + padding * 2
property var flipped: false
x: parent.width - UM.Theme.getSize("default_lining").width
y: {
// Checks if popup is more than halfway down the screen AND further than 400 down (this avoids popup going off the top of screen)
// If it is then the popup will push up instead of down
// This fixes the popups appearing bellow the bottom of the screen.
if (materialBrandMenu.parent.height / 2 < parent.y && parent.y > 400) {
flipped = true
return -UM.Theme.getSize("default_lining").width - height + UM.Theme.getSize("menu").height
}
flipped = false
return -UM.Theme.getSize("default_lining").width
}
padding: background.border.width
// Nasty hack to ensure that we can keep track if the popup contains the mouse.
// Since we also want a hover for the sub items (and these events are sent async)
// We have to keep a count of itemHovered (instead of just a bool)
property int itemHovered: 0
MouseArea
{
id: submenuArea
@ -120,16 +103,11 @@ Cura.MenuItem
onEntered: hideTimer.restartTimer()
}
background: Rectangle
{
color: UM.Theme.getColor("main_background")
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
}
Column
{
id: materialTypesList
width: UM.Theme.getSize("menu").width
height: childrenRect.height
spacing: 0
property var brandMaterials: materialTypesModel.material_types
@ -146,9 +124,7 @@ Cura.MenuItem
height: UM.Theme.getSize("menu").height
width: UM.Theme.getSize("menu").width
color: materialTypeButton.containsMouse ? UM.Theme.getColor("background_2") : UM.Theme.getColor("background_1")
property var isFlipped: menuPopup.flipped
color: materialTypeButton.containsMouse ? UM.Theme.getColor("background_2") : "transparent"
RowLayout
{
@ -236,34 +212,17 @@ Cura.MenuItem
onTriggered: colorPopup.close()
}
Popup
MaterialBrandSubMenu
{
id: colorPopup
width: materialColorsList.width + padding * 2
height: materialColorsList.height + padding * 2
x: parent.width
y: {
// If flipped the popup should push up rather than down from the parent
if (brandMaterialBase.isFlipped) {
return -height + UM.Theme.getSize("menu").height + UM.Theme.getSize("default_lining").width
}
return -UM.Theme.getSize("default_lining").width
}
property int itemHovered: 0
padding: background.border.width
background: Rectangle
{
color: UM.Theme.getColor("main_background")
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
}
Column
{
id: materialColorsList
property var brandColors: model.colors
width: UM.Theme.getSize("menu").width
height: childrenRect.height
spacing: 0
Repeater
@ -273,12 +232,38 @@ Cura.MenuItem
delegate: Rectangle
{
height: UM.Theme.getSize("menu").height
width: UM.Theme.getSize("menu").width
width: parent.width
color: materialColorButton.containsMouse ? UM.Theme.getColor("background_2") : UM.Theme.getColor("background_1")
color: materialColorButton.containsMouse ? UM.Theme.getColor("background_2") : UM.Theme.getColor("main_background")
MouseArea
{
id: materialColorButton
anchors.fill: parent
hoverEnabled: true
onClicked:
{
Cura.MachineManager.setMaterial(extruderIndex, model.container_node);
menuPopup.close();
colorPopup.close();
materialMenu.close();
}
onEntered:
{
menuPopup.itemHovered += 1;
colorPopup.itemHovered += 1;
}
onExited:
{
menuPopup.itemHovered -= 1;
colorPopup.itemHovered -= 1;
}
}
Item
{
height: parent.height
width: parent.width
opacity: materialBrandMenu.enabled ? 1 : 0.5
anchors.fill: parent
@ -309,31 +294,6 @@ Cura.MenuItem
wrapMode: Text.NoWrap
}
}
MouseArea
{
id: materialColorButton
anchors.fill: parent
hoverEnabled: true
onClicked:
{
Cura.MachineManager.setMaterial(extruderIndex, model.container_node);
menuPopup.close();
colorPopup.close();
materialMenu.close();
}
onEntered:
{
menuPopup.itemHovered += 1;
colorPopup.itemHovered += 1;
}
onExited:
{
menuPopup.itemHovered -= 1;
colorPopup.itemHovered -= 1;
}
}
}
}
}

View File

@ -0,0 +1,118 @@
// Copyright (c) 2022 UltiMaker
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.4
import QtQuick.Layouts 2.7
import UM 1.5 as UM
import Cura 1.7 as Cura
Popup
{
id: materialBrandSubMenu
bottomPadding: UM.Theme.getSize("thin_margin").height
topPadding: UM.Theme.getSize("thin_margin").height
implicitWidth: scrollViewContent.width + scrollbar.width + leftPadding + rightPadding
implicitHeight: scrollViewContent.height + bottomPadding + topPadding
// offset position relative to the parent
property int implicitX: parent.width
property int implicitY: -UM.Theme.getSize("thin_margin").height
default property alias contents: scrollViewContent.children
x: implicitX
y: implicitY
// needed for the `mapToItem` function to work; apparently a Popup is not an Item
Item
{
id: materialBrandSubMenuItem
anchors.fill: parent
}
onOpened:
{
// we want to make sure here that the popup never goes out side the window so we adjust the x and y position
// based on the width/height of the mainWindow/popup. QML is a bit weird here though, as the globalPosition
// is in absolute coordinates relative to the origin of the mainWindow while setting the x and y coordinates
// of the popup only changes the position relative to the parent.
// reset position, the remainder of the function asumes this position and size
materialBrandSubMenu.x = implicitX;
materialBrandSubMenu.y = implicitY;
materialBrandSubMenu.width = implicitWidth;
materialBrandSubMenu.height = implicitHeight;
const globalPosition = materialBrandSubMenuItem.mapToItem(null, 0, 0);
if (globalPosition.y > mainWindow.height - materialBrandSubMenu.height)
{
if (mainWindow.height > materialBrandSubMenu.height)
{
const targetY = mainWindow.height - materialBrandSubMenu.height;
const deltaY = globalPosition.y - targetY;
materialBrandSubMenu.y = implicitY - deltaY;
}
else
{
// if popup is taller then the the component, limit
// the components height and set the position to
// y = 0 (in absolute coordinates)
materialBrandSubMenu.y = implicitY - globalPosition.y;
materialBrandSubMenu.height = mainWindow.height;
}
}
if (globalPosition.x > mainWindow.width - materialBrandSubMenu.width)
{
if (mainWindow.width > materialBrandSubMenu.width)
{
const targetX = mainWindow.width - materialBrandSubMenu.width;
const deltaX = globalPosition.x - targetX;
materialBrandSubMenu.x = implicitX - deltaX;
}
else
{
materialBrandSubMenu.x = implicitX - globalPosition.x;
materialBrandSubMenu.width = mainWindow.width;
}
}
}
padding: background.border.width
background: Rectangle
{
color: UM.Theme.getColor("main_background")
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
}
ScrollView
{
id: scrollView
anchors.fill: parent
contentHeight: scrollViewContent.height
clip: true
ScrollBar.vertical: UM.ScrollBar
{
id: scrollbar
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
}
Rectangle
{
id: scrollViewContent
width: childrenRect.width
height: childrenRect.height
color: UM.Theme.getColor("main_background")
}
}
}