123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- // 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
- 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
- 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
- {
- id: brandMaterialBase
- 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
- 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: {
- // 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
- 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.ColorImage
- {
- 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;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
|