Browse Source

Merge pull request #4137 from Ultimaker/CURA-5595_add_custom_button_to_menu

Cura 5595 add custom button to menu
alekseisasin 6 years ago
parent
commit
7af6672547

+ 1 - 0
cura/API/Backups.py

@@ -13,6 +13,7 @@ from cura.Backups.BackupsManager import BackupsManager
 #       api = CuraAPI()
 #       api.backups.createBackup()
 #       api.backups.restoreBackup(my_zip_file, {"cura_release": "3.1"})``
+
 class Backups:
     manager = BackupsManager()  # Re-used instance of the backups manager.
 

+ 33 - 0
cura/API/Interface/Settings.py

@@ -0,0 +1,33 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from cura.CuraApplication import CuraApplication
+
+##  The Interface.Settings API provides a version-proof bridge between Cura's
+#   (currently) sidebar UI and plug-ins that hook into it.
+#
+#   Usage:
+#       ``from cura.API import CuraAPI
+#       api = CuraAPI()
+#       api.interface.settings.getContextMenuItems()
+#       data = {
+#           "name": "My Plugin Action",
+#           "iconName": "my-plugin-icon",
+#           "actions": my_menu_actions,
+#           "menu_item": MyPluginAction(self)
+#       }
+#       api.interface.settings.addContextMenuItem(data)``
+
+class Settings:
+    # Re-used instance of Cura:
+    application = CuraApplication.getInstance()  # type: CuraApplication
+
+    ##  Add items to the sidebar context menu.
+    #   \param menu_item dict containing the menu item to add.
+    def addContextMenuItem(self, menu_item: dict) -> None:
+        self.application.addSidebarCustomMenuItem(menu_item)
+
+    ##  Get all custom items currently added to the sidebar context menu.
+    #   \return List containing all custom context menu items.
+    def getContextMenuItems(self) -> list:
+        return self.application.getSidebarCustomMenuItems()

+ 24 - 0
cura/API/Interface/__init__.py

@@ -0,0 +1,24 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from UM.PluginRegistry import PluginRegistry
+from cura.API.Interface.Settings import Settings
+
+##  The Interface class serves as a common root for the specific API
+#   methods for each interface element.
+#
+#   Usage:
+#       ``from cura.API import CuraAPI
+#       api = CuraAPI()
+#       api.interface.settings.addContextMenuItem()
+#       api.interface.viewport.addOverlay() # Not implemented, just a hypothetical
+#       api.interface.toolbar.getToolButtonCount() # Not implemented, just a hypothetical
+#       # etc.``
+
+class Interface:
+
+    # For now we use the same API version to be consistent.
+    VERSION = PluginRegistry.APIVersion
+
+    # API methods specific to the settings portion of the UI
+    settings = Settings()

+ 6 - 1
cura/API/__init__.py

@@ -2,6 +2,7 @@
 # Cura is released under the terms of the LGPLv3 or higher.
 from UM.PluginRegistry import PluginRegistry
 from cura.API.Backups import Backups
+from cura.API.Interface import Interface
 
 ##  The official Cura API that plug-ins can use to interact with Cura.
 #
@@ -9,10 +10,14 @@ from cura.API.Backups import Backups
 #   this API provides a version-safe interface with proper deprecation warnings
 #   etc. Usage of any other methods than the ones provided in this API can cause
 #   plug-ins to be unstable.
+
 class CuraAPI:
 
     # For now we use the same API version to be consistent.
     VERSION = PluginRegistry.APIVersion
 
-    # Backups API.
+    # Backups API
     backups = Backups()
+
+    # Interface API
+    interface = Interface()

+ 12 - 0
cura/CuraApplication.py

@@ -104,6 +104,7 @@ from cura.Settings.UserChangesModel import UserChangesModel
 from cura.Settings.ExtrudersModel import ExtrudersModel
 from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
 from cura.Settings.ContainerManager import ContainerManager
+from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
 
 from cura.ObjectsModel import ObjectsModel
 
@@ -226,6 +227,8 @@ class CuraApplication(QtApplication):
 
         self._need_to_show_user_agreement = True
 
+        self._sidebar_custom_menu_items = []  # type: list # Keeps list of custom menu items for the side bar
+
         self._plugins_loaded = False
 
         # Backups
@@ -944,6 +947,7 @@ class CuraApplication(QtApplication):
         qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
         qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel")
         qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance)
+        qmlRegisterType(SidebarCustomMenuItemsModel, "Cura", 1, 0, "SidebarCustomMenuItemsModel")
 
         # As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
         actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
@@ -1731,3 +1735,11 @@ class CuraApplication(QtApplication):
     @pyqtSlot()
     def showMoreInformationDialogForAnonymousDataCollection(self):
         cast(SliceInfo, self._plugin_registry.getPluginObject("SliceInfoPlugin")).showMoreInfoDialog()
+
+
+    def addSidebarCustomMenuItem(self, menu_item: list) -> None:
+        self._sidebar_custom_menu_items.append(menu_item)
+
+    def getSidebarCustomMenuItems(self) -> list:
+        return self._sidebar_custom_menu_items
+

+ 41 - 0
cura/Settings/SidebarCustomMenuItemsModel.py

@@ -0,0 +1,41 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Any
+
+from UM.Qt.ListModel import ListModel
+from PyQt5.QtCore import pyqtSlot, Qt
+
+
+class SidebarCustomMenuItemsModel(ListModel):
+    NameRole = Qt.UserRole + 1
+    ActionsRole = Qt.UserRole + 2
+    MenuItemRole = Qt.UserRole + 3
+    MenuItemIconNameRole = Qt.UserRole + 5
+
+    def __init__(self, parent=None):
+        super().__init__(parent)
+        self.addRoleName(self.NameRole, "name")
+        self.addRoleName(self.ActionsRole, "actions")
+        self.addRoleName(self.MenuItemRole, "menu_item")
+        self.addRoleName(self.MenuItemIconNameRole, "iconName")
+        self._updateExtensionList()
+
+    def _updateExtensionList(self)-> None:
+        from cura.CuraApplication import CuraApplication
+        for menu_item in CuraApplication.getInstance().getSidebarCustomMenuItems():
+
+            self.appendItem({
+                    "name": menu_item["name"],
+                    "iconName": menu_item["iconName"],
+                    "actions": menu_item["actions"],
+                    "menu_item": menu_item["menu_item"]
+                })
+
+    @pyqtSlot(str, "QVariantList", "QVariantMap")
+    def callMenuItemMethod(self, menu_item_name: str, menu_item_actions: list, kwargs: Any)-> None:
+        for item in self._items:
+            if menu_item_name == item["name"]:
+                for method in menu_item_actions:
+                    getattr(item["menu_item"], method)(kwargs)
+                break

+ 22 - 0
resources/qml/Settings/SettingView.qml

@@ -561,6 +561,28 @@ Item
                     visible: machineExtruderCount.properties.value > 1
                 }
 
+                Instantiator
+                {
+                    id: customMenuItems
+                    model: Cura.SidebarCustomMenuItemsModel { }
+                    MenuItem
+                    {
+                        text: model.name
+                        iconName: model.iconName
+                        onTriggered:
+                        {
+                            customMenuItems.model.callMenuItemMethod(name, model.actions, {"key": contextMenu.key})
+                        }
+                    }
+                   onObjectAdded: contextMenu.insertItem(index, object)
+                   onObjectRemoved: contextMenu.removeItem(object)
+                }
+
+                MenuSeparator
+                {
+                    visible: customMenuItems.count > 0
+                }
+
                 MenuItem
                 {
                     //: Settings context menu action