Cura/resources/qml/Menus/MaterialBrandMenu.qml
Ghostkeeper 90a3b4cde6
Use 250ms delay everywhere
This looks like it's consistent with the normal menus. And it fixes the issue where multiple menus can be shown at once because it would hide slower than show the next one.

Contributes to issue CURA-8640.
2022-04-08 17:02:52 +02:00

322 lines
12 KiB
QML

// Copyright (c) 2022 Ultimaker B.V.
// 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
/* This element is a workaround for MacOS, where it can crash in Qt6 when nested menus are closed.
Instead we'll use a pop-up which doesn't seem to have that problem. */
Cura.MenuItem
{
id: materialBrandMenu
overrideShowArrow: true
property var materialTypesModel
text: materialTypesModel.name
contentItem: MouseArea
{
hoverEnabled: true
RowLayout
{
spacing: 0
opacity: materialBrandMenu.enabled ? 1 : 0.5
Item
{
// Spacer
width: UM.Theme.getSize("default_margin").width
}
UM.Label
{
text: replaceText(materialBrandMenu.text)
Layout.fillWidth: true
Layout.fillHeight:true
elide: Label.ElideRight
wrapMode: Text.NoWrap
}
Item
{
Layout.fillWidth: true
}
Item
{
// Right side margin
width: UM.Theme.getSize("default_margin").width
}
}
onEntered: showTimer.restartTimer()
onExited: hideTimer.restartTimer()
}
Timer
{
id: showTimer
interval: 250
function restartTimer()
{
restart();
running = Qt.binding(function() { return materialBrandMenu.enabled && materialBrandMenu.contentItem.containsMouse; });
hideTimer.running = false;
}
onTriggered: menuPopup.open()
}
Timer
{
id: hideTimer
interval: 250
function restartTimer() //Restart but re-evaluate the running property then.
{
restart();
running = Qt.binding(function() { return materialBrandMenu.enabled && !materialBrandMenu.contentItem.containsMouse && !menuPopup.itemHovered > 0; });
showTimer.running = false;
}
onTriggered: menuPopup.close()
}
Popup
{
id: menuPopup
x: parent.width - UM.Theme.getSize("default_lining").width
y: -UM.Theme.getSize("default_lining").width
width: materialTypesList.width + padding * 2
height: materialTypesList.height + padding * 2
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
anchors.fill: parent
hoverEnabled: true
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
spacing: 0
property var brandMaterials: materialTypesModel.material_types
Repeater
{
model: parent.brandMaterials
//Use a MouseArea and Rectangle, not a button, because the button grabs mouse events which makes the parent pop-up think it's no longer being hovered.
//With a custom MouseArea, we can prevent the events from being accepted.
delegate: Rectangle
{
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")
RowLayout
{
spacing: 0
opacity: materialBrandMenu.enabled ? 1 : 0.5
height: parent.height
width: parent.width
Item
{
// Spacer
width: UM.Theme.getSize("default_margin").width
}
UM.Label
{
text: model.name
Layout.fillWidth: true
Layout.fillHeight: true
elide: Label.ElideRight
wrapMode: Text.NoWrap
}
Item
{
Layout.fillWidth: true
}
UM.ColorImage
{
height: UM.Theme.getSize("default_arrow").height
width: UM.Theme.getSize("default_arrow").width
color: UM.Theme.getColor("setting_control_text")
source: UM.Theme.getIcon("ChevronSingleRight")
}
Item
{
// Right side margin
width: UM.Theme.getSize("default_margin").width
}
}
MouseArea
{
id: materialTypeButton
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
onEntered:
{
menuPopup.itemHovered += 1;
showSubTimer.restartTimer();
}
onExited:
{
menuPopup.itemHovered -= 1;
hideSubTimer.restartTimer();
}
}
Timer
{
id: showSubTimer
interval: 250
function restartTimer()
{
restart();
running = Qt.binding(function() { return materialTypeButton.containsMouse; });
hideSubTimer.running = false;
}
onTriggered: colorPopup.open()
}
Timer
{
id: hideSubTimer
interval: 250
function restartTimer() //Restart but re-evaluate the running property then.
{
restart();
running = Qt.binding(function() { return !materialTypeButton.containsMouse && !colorPopup.itemHovered > 0; });
showSubTimer.running = false;
}
onTriggered: colorPopup.close()
}
Popup
{
id: colorPopup
width: materialColorsList.width + padding * 2
height: materialColorsList.height + padding * 2
x: parent.width
y: -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
spacing: 0
Repeater
{
model: parent.brandColors
delegate: Rectangle
{
height: UM.Theme.getSize("menu").height
width: UM.Theme.getSize("menu").width
color: materialColorButton.containsMouse ? UM.Theme.getColor("background_2") : UM.Theme.getColor("background_1")
Item
{
opacity: materialBrandMenu.enabled ? 1 : 0.5
anchors.fill: parent
//Checkmark, if the material is selected.
UM.RecolorImage
{
id: checkmark
visible: model.id === materialMenu.activeMaterialId
height: UM.Theme.getSize("default_arrow").height
width: height
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
source: UM.Theme.getIcon("Check", "low")
color: UM.Theme.getColor("setting_control_text")
}
UM.Label
{
text: model.name
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width + UM.Theme.getSize("default_arrow").height
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
elide: Label.ElideRight
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;
}
}
}
}
}
}
}
}
}
}
}