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

Cura 5595 add custom button to menu
This commit is contained in:
alekseisasin 2018-08-13 09:56:32 +02:00 committed by GitHub
commit 7af6672547
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 139 additions and 1 deletions

View File

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

View File

@ -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()

View File

@ -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()

View File

@ -2,6 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from cura.API.Backups import Backups 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. ## 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 # 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 # etc. Usage of any other methods than the ones provided in this API can cause
# plug-ins to be unstable. # plug-ins to be unstable.
class CuraAPI: class CuraAPI:
# For now we use the same API version to be consistent. # For now we use the same API version to be consistent.
VERSION = PluginRegistry.APIVersion VERSION = PluginRegistry.APIVersion
# Backups API. # Backups API
backups = Backups() backups = Backups()
# Interface API
interface = Interface()

View File

@ -104,6 +104,7 @@ from cura.Settings.UserChangesModel import UserChangesModel
from cura.Settings.ExtrudersModel import ExtrudersModel from cura.Settings.ExtrudersModel import ExtrudersModel
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
from cura.Settings.ContainerManager import ContainerManager from cura.Settings.ContainerManager import ContainerManager
from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
from cura.ObjectsModel import ObjectsModel from cura.ObjectsModel import ObjectsModel
@ -226,6 +227,8 @@ class CuraApplication(QtApplication):
self._need_to_show_user_agreement = True 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 self._plugins_loaded = False
# Backups # Backups
@ -944,6 +947,7 @@ class CuraApplication(QtApplication):
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator") qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel") qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel")
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance) 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. # 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"))) actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
@ -1731,3 +1735,11 @@ class CuraApplication(QtApplication):
@pyqtSlot() @pyqtSlot()
def showMoreInformationDialogForAnonymousDataCollection(self): def showMoreInformationDialogForAnonymousDataCollection(self):
cast(SliceInfo, self._plugin_registry.getPluginObject("SliceInfoPlugin")).showMoreInfoDialog() 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

View File

@ -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

View File

@ -561,6 +561,28 @@ Item
visible: machineExtruderCount.properties.value > 1 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 MenuItem
{ {
//: Settings context menu action //: Settings context menu action