Просмотр исходного кода

Replace material sub-menus with custom Popup

The sub-menus were giving segfaults for some reason. We couldn't figure out how to circumvent that. So now we're at a last resort: Implement the whole thing ourselves, but with Popup instead of Menu.

Contributes to issue CURA-8640.
Ghostkeeper 2 лет назад
Родитель
Сommit
11b557b3d9

+ 101 - 0
resources/qml/Menus/MaterialBrandMenu.qml

@@ -0,0 +1,101 @@
+// 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
+
+    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: 100
+        function restartTimer()
+        {
+            restart();
+            running = 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 = materialBrandMenu.enabled && !materialBrandMenu.contentItem.containsMouse && !submenuArea.containsMouse;
+            showTimer.running = false;
+        }
+        onTriggered: menuPopup.close()
+    }
+
+    Popup
+    {
+        id: menuPopup
+        x: parent.width
+        y: 0
+        width: 100
+        height: 100
+
+        MouseArea
+        {
+            id: submenuArea
+            anchors.fill: parent
+
+            hoverEnabled: true
+            onEntered: hideTimer.restartTimer()
+        }
+    }
+}

+ 4 - 37
resources/qml/Menus/MaterialMenu.qml

@@ -98,45 +98,12 @@ Cura.Menu
     Instantiator
     {
         model: brandModel
-        Cura.Menu
+        delegate: Cura.MaterialBrandMenu
         {
-            id: brandMenu
-            title: brandName
-            property string brandName: model.name
-            property var brandMaterials: model.material_types
-
-            Instantiator
-            {
-                model: brandMaterials
-                delegate: Cura.Menu
-                {
-                    id: brandMaterialsMenu
-                    title: materialName
-                    property string materialName: model.name
-                    property var brandMaterialColors: model.colors
-
-                    Instantiator
-                    {
-                        model: brandMaterialColors
-                        delegate: Cura.MenuItem
-                        {
-                            text: model.name
-                            checkable: true
-                            enabled: isActiveExtruderEnabled
-                            checked: model.id === materialMenu.activeMaterialId
-
-                            onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node)
-                        }
-                        onObjectAdded: function(index, object) { brandMaterialsMenu.insertItem(index, object)}
-                        onObjectRemoved: function(object) {brandMaterialsMenu.removeItem(object)}
-                    }
-                }
-                onObjectAdded: function(index, object) { brandMenu.insertMenu(index, object)}
-                onObjectRemoved: function(object) {brandMenu.removeMenu(object)}
-            }
+            text: model.name
         }
-        onObjectAdded: function(index, object) {materialMenu.insertMenu(index + 4, object)}
-        onObjectRemoved: function(object) { materialMenu.removeMenu(object)}
+        onObjectAdded: function(index, object) { materialMenu.insertItem(index + 4, object)}
+        onObjectRemoved: function(object) { materialMenu.removeItem(index) }
     }
 
     Cura.MenuSeparator {}

+ 3 - 1
resources/qml/Widgets/MenuItem.qml

@@ -16,9 +16,11 @@ UM.MenuItem
     implicitHeight: UM.Theme.getSize("menu").height + UM.Theme.getSize("narrow_margin").height
     implicitWidth: UM.Theme.getSize("menu").width
 
+    property bool overrideShowArrow: false
+
     arrow: UM.RecolorImage
     {
-        visible: menuItem.subMenu
+        visible: menuItem.subMenu || overrideShowArrow
         height: UM.Theme.getSize("default_arrow").height
         width: height
         anchors.verticalCenter: parent.verticalCenter