Merge remote-tracking branch 'origin/3.5' into CURA-5718_fix_upgrade_for_bundled_plugins

This commit is contained in:
Lipu Fei 2018-09-17 16:22:22 +02:00
commit a4b20e046d
15 changed files with 435 additions and 405 deletions

View file

@ -482,7 +482,9 @@ class CuraApplication(QtApplication):
preferences.addPreference("view/filter_current_build_plate", False) preferences.addPreference("view/filter_current_build_plate", False)
preferences.addPreference("cura/sidebar_collapsed", False) preferences.addPreference("cura/sidebar_collapsed", False)
preferences.addPreference("cura/favorite_materials", ";".join([])) preferences.addPreference("cura/favorite_materials", "")
preferences.addPreference("cura/expanded_brands", "")
preferences.addPreference("cura/expanded_types", "")
self._need_to_show_user_agreement = not preferences.getValue("general/accepted_user_agreement") self._need_to_show_user_agreement = not preferences.getValue("general/accepted_user_agreement")

View file

@ -40,7 +40,6 @@ if TYPE_CHECKING:
class MaterialManager(QObject): class MaterialManager(QObject):
materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated. materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated.
favoritesUpdated = pyqtSignal() # Emitted whenever the favorites are changed
def __init__(self, container_registry, parent = None): def __init__(self, container_registry, parent = None):
super().__init__(parent) super().__init__(parent)
@ -196,12 +195,11 @@ class MaterialManager(QObject):
for material_metadata in material_metadatas.values(): for material_metadata in material_metadatas.values():
self.__addMaterialMetadataIntoLookupTree(material_metadata) self.__addMaterialMetadataIntoLookupTree(material_metadata)
self.materialsUpdated.emit()
favorites = self._application.getPreferences().getValue("cura/favorite_materials") favorites = self._application.getPreferences().getValue("cura/favorite_materials")
for item in favorites.split(";"): for item in favorites.split(";"):
self._favorites.add(item) self._favorites.add(item)
self.favoritesUpdated.emit()
self.materialsUpdated.emit()
def __addMaterialMetadataIntoLookupTree(self, material_metadata: dict) -> None: def __addMaterialMetadataIntoLookupTree(self, material_metadata: dict) -> None:
material_id = material_metadata["id"] material_id = material_metadata["id"]
@ -621,7 +619,7 @@ class MaterialManager(QObject):
@pyqtSlot(str) @pyqtSlot(str)
def addFavorite(self, root_material_id: str): def addFavorite(self, root_material_id: str):
self._favorites.add(root_material_id) self._favorites.add(root_material_id)
self.favoritesUpdated.emit() self.materialsUpdated.emit()
# Ensure all settings are saved. # Ensure all settings are saved.
self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites))) self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites)))
@ -630,7 +628,7 @@ class MaterialManager(QObject):
@pyqtSlot(str) @pyqtSlot(str)
def removeFavorite(self, root_material_id: str): def removeFavorite(self, root_material_id: str):
self._favorites.remove(root_material_id) self._favorites.remove(root_material_id)
self.favoritesUpdated.emit() self.materialsUpdated.emit()
# Ensure all settings are saved. # Ensure all settings are saved.
self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites))) self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites)))

View file

@ -34,9 +34,6 @@ class BaseMaterialsModel(ListModel):
# Update this model when list of materials changes # Update this model when list of materials changes
self._material_manager.materialsUpdated.connect(self._update) self._material_manager.materialsUpdated.connect(self._update)
# Update this model when list of favorites changes
self._material_manager.favoritesUpdated.connect(self._update)
self.addRoleName(Qt.UserRole + 1, "root_material_id") self.addRoleName(Qt.UserRole + 1, "root_material_id")
self.addRoleName(Qt.UserRole + 2, "id") self.addRoleName(Qt.UserRole + 2, "id")
self.addRoleName(Qt.UserRole + 3, "GUID") self.addRoleName(Qt.UserRole + 3, "GUID")

View file

@ -12,7 +12,8 @@ class MaterialTypesModel(ListModel):
super().__init__(parent) super().__init__(parent)
self.addRoleName(Qt.UserRole + 1, "name") self.addRoleName(Qt.UserRole + 1, "name")
self.addRoleName(Qt.UserRole + 2, "colors") self.addRoleName(Qt.UserRole + 2, "brand")
self.addRoleName(Qt.UserRole + 3, "colors")
class MaterialBrandsModel(BaseMaterialsModel): class MaterialBrandsModel(BaseMaterialsModel):
@ -86,6 +87,7 @@ class MaterialBrandsModel(BaseMaterialsModel):
for material_type, material_list in material_dict.items(): for material_type, material_list in material_dict.items():
material_type_item = { material_type_item = {
"name": material_type, "name": material_type,
"brand": brand,
"colors": BaseMaterialsModel(self) "colors": BaseMaterialsModel(self)
} }
material_type_item["colors"].clear() material_type_item["colors"].clear()

View file

@ -39,6 +39,7 @@ Item {
property real lowerValue: minimumValue property real lowerValue: minimumValue
property bool layersVisible: true property bool layersVisible: true
property bool manuallyChanged: true // Indicates whether the value was changed manually or during simulation
function getUpperValueFromSliderHandle() { function getUpperValueFromSliderHandle() {
return upperHandle.getValue() return upperHandle.getValue()
@ -96,7 +97,8 @@ Item {
visible: sliderRoot.layersVisible visible: sliderRoot.layersVisible
// set the new value when dragging // set the new value when dragging
function onHandleDragged () { function onHandleDragged() {
sliderRoot.manuallyChanged = true
upperHandle.y = y - upperHandle.height upperHandle.y = y - upperHandle.height
lowerHandle.y = y + height lowerHandle.y = y + height
@ -109,7 +111,7 @@ Item {
UM.SimulationView.setMinimumLayer(lowerValue) UM.SimulationView.setMinimumLayer(lowerValue)
} }
function setValue (value) { function setValue(value) {
var range = sliderRoot.upperValue - sliderRoot.lowerValue var range = sliderRoot.upperValue - sliderRoot.lowerValue
value = Math.min(value, sliderRoot.maximumValue) value = Math.min(value, sliderRoot.maximumValue)
value = Math.max(value, sliderRoot.minimumValue + range) value = Math.max(value, sliderRoot.minimumValue + range)
@ -168,7 +170,8 @@ Item {
color: upperHandleLabel.activeFocus ? sliderRoot.handleActiveColor : sliderRoot.upperHandleColor color: upperHandleLabel.activeFocus ? sliderRoot.handleActiveColor : sliderRoot.upperHandleColor
visible: sliderRoot.layersVisible visible: sliderRoot.layersVisible
function onHandleDragged () { function onHandleDragged() {
sliderRoot.manuallyChanged = true
// don't allow the lower handle to be heigher than the upper handle // don't allow the lower handle to be heigher than the upper handle
if (lowerHandle.y - (y + height) < sliderRoot.minimumRangeHandleSize) { if (lowerHandle.y - (y + height) < sliderRoot.minimumRangeHandleSize) {
@ -183,7 +186,7 @@ Item {
} }
// get the upper value based on the slider position // get the upper value based on the slider position
function getValue () { function getValue() {
var result = y / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)) var result = y / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize))
result = sliderRoot.maximumValue + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumValue)) result = sliderRoot.maximumValue + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumValue))
result = sliderRoot.roundValues ? Math.round(result) : result result = sliderRoot.roundValues ? Math.round(result) : result
@ -191,7 +194,7 @@ Item {
} }
// set the slider position based on the upper value // set the slider position based on the upper value
function setValue (value) { function setValue(value) {
// Normalize values between range, since using arrow keys will create out-of-the-range values // Normalize values between range, since using arrow keys will create out-of-the-range values
value = sliderRoot.normalizeValue(value) value = sliderRoot.normalizeValue(value)
@ -205,8 +208,16 @@ Item {
sliderRoot.updateRangeHandle() sliderRoot.updateRangeHandle()
} }
Keys.onUpPressed: upperHandleLabel.setValue(upperHandleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) Keys.onUpPressed:
Keys.onDownPressed: upperHandleLabel.setValue(upperHandleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) {
sliderRoot.manuallyChanged = true
upperHandleLabel.setValue(upperHandleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
}
Keys.onDownPressed:
{
sliderRoot.manuallyChanged = true
upperHandleLabel.setValue(upperHandleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
}
// dragging // dragging
MouseArea { MouseArea {
@ -256,7 +267,8 @@ Item {
visible: sliderRoot.layersVisible visible: sliderRoot.layersVisible
function onHandleDragged () { function onHandleDragged() {
sliderRoot.manuallyChanged = true
// don't allow the upper handle to be lower than the lower handle // don't allow the upper handle to be lower than the lower handle
if (y - (upperHandle.y + upperHandle.height) < sliderRoot.minimumRangeHandleSize) { if (y - (upperHandle.y + upperHandle.height) < sliderRoot.minimumRangeHandleSize) {
@ -271,7 +283,7 @@ Item {
} }
// get the lower value from the current slider position // get the lower value from the current slider position
function getValue () { function getValue() {
var result = (y - (sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)) / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)); var result = (y - (sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)) / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize));
result = sliderRoot.maximumValue - sliderRoot.minimumRange + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumRange)) result = sliderRoot.maximumValue - sliderRoot.minimumRange + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumRange))
result = sliderRoot.roundValues ? Math.round(result) : result result = sliderRoot.roundValues ? Math.round(result) : result
@ -279,7 +291,7 @@ Item {
} }
// set the slider position based on the lower value // set the slider position based on the lower value
function setValue (value) { function setValue(value) {
// Normalize values between range, since using arrow keys will create out-of-the-range values // Normalize values between range, since using arrow keys will create out-of-the-range values
value = sliderRoot.normalizeValue(value) value = sliderRoot.normalizeValue(value)

View file

@ -34,6 +34,7 @@ Item {
property real handleValue: maximumValue property real handleValue: maximumValue
property bool pathsVisible: true property bool pathsVisible: true
property bool manuallyChanged: true // Indicates whether the value was changed manually or during simulation
function getHandleValueFromSliderHandle () { function getHandleValueFromSliderHandle () {
return handle.getValue() return handle.getValue()
@ -97,6 +98,7 @@ Item {
visible: sliderRoot.pathsVisible visible: sliderRoot.pathsVisible
function onHandleDragged () { function onHandleDragged () {
sliderRoot.manuallyChanged = true
// update the range handle // update the range handle
sliderRoot.updateRangeHandle() sliderRoot.updateRangeHandle()
@ -128,8 +130,16 @@ Item {
sliderRoot.updateRangeHandle() sliderRoot.updateRangeHandle()
} }
Keys.onRightPressed: handleLabel.setValue(handleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) Keys.onRightPressed:
Keys.onLeftPressed: handleLabel.setValue(handleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) {
sliderRoot.manuallyChanged = true
handleLabel.setValue(handleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
}
Keys.onLeftPressed:
{
sliderRoot.manuallyChanged = true
handleLabel.setValue(handleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
}
// dragging // dragging
MouseArea { MouseArea {

View file

@ -623,7 +623,15 @@ Item
{ {
target: UM.SimulationView target: UM.SimulationView
onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath)
onCurrentPathChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) onCurrentPathChanged:
{
// Only pause the simulation when the layer was changed manually, not when the simulation is running
if (pathSlider.manuallyChanged)
{
playButton.pauseSimulation()
}
pathSlider.setHandleValue(UM.SimulationView.currentPath)
}
} }
// make sure the slider handlers show the correct value after switching views // make sure the slider handlers show the correct value after switching views
@ -667,9 +675,14 @@ Item
{ {
target: UM.SimulationView target: UM.SimulationView
onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer) onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer)
onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer)
onCurrentLayerChanged: onCurrentLayerChanged:
{
// Only pause the simulation when the layer was changed manually, not when the simulation is running
if (layerSlider.manuallyChanged)
{ {
playButton.pauseSimulation() playButton.pauseSimulation()
}
layerSlider.setUpperValue(UM.SimulationView.currentLayer) layerSlider.setUpperValue(UM.SimulationView.currentLayer)
} }
} }
@ -719,6 +732,8 @@ Item
iconSource = "./resources/simulation_resume.svg" iconSource = "./resources/simulation_resume.svg"
simulationTimer.stop() simulationTimer.stop()
status = 0 status = 0
layerSlider.manuallyChanged = true
pathSlider.manuallyChanged = true
} }
function resumeSimulation() function resumeSimulation()
@ -726,7 +741,8 @@ Item
UM.SimulationView.setSimulationRunning(true) UM.SimulationView.setSimulationRunning(true)
iconSource = "./resources/simulation_pause.svg" iconSource = "./resources/simulation_pause.svg"
simulationTimer.start() simulationTimer.start()
status = 1 layerSlider.manuallyChanged = false
pathSlider.manuallyChanged = false
} }
} }
@ -770,7 +786,6 @@ Item
{ {
UM.SimulationView.setCurrentLayer(currentLayer+1) UM.SimulationView.setCurrentLayer(currentLayer+1)
UM.SimulationView.setCurrentPath(0) UM.SimulationView.setCurrentPath(0)
playButton.resumeSimulation()
} }
} }
else else
@ -778,6 +793,8 @@ Item
UM.SimulationView.setCurrentPath(currentPath+1) UM.SimulationView.setCurrentPath(currentPath+1)
} }
} }
// The status must be set here instead of in the resumeSimulation function otherwise it won't work
// correctly, because part of the logic is in this trigger function.
playButton.status = 1 playButton.status = 1
} }
} }

View file

@ -39,7 +39,7 @@ class Toolbox(QObject, Extension):
self._application = application # type: CuraApplication self._application = application # type: CuraApplication
self._sdk_version = None # type: Optional[int] self._sdk_version = None # type: Optional[Union[str, int]]
self._cloud_api_version = None # type: Optional[int] self._cloud_api_version = None # type: Optional[int]
self._cloud_api_root = None # type: Optional[str] self._cloud_api_root = None # type: Optional[str]
self._api_url = None # type: Optional[str] self._api_url = None # type: Optional[str]
@ -207,7 +207,7 @@ class Toolbox(QObject, Extension):
return cura.CuraVersion.CuraCloudAPIVersion # type: ignore return cura.CuraVersion.CuraCloudAPIVersion # type: ignore
# Get the packages version depending on Cura version settings. # Get the packages version depending on Cura version settings.
def _getSDKVersion(self) -> int: def _getSDKVersion(self) -> Union[int, str]:
if not hasattr(cura, "CuraVersion"): if not hasattr(cura, "CuraVersion"):
return self._plugin_registry.APIVersion return self._plugin_registry.APIVersion
if not hasattr(cura.CuraVersion, "CuraSDKVersion"): # type: ignore if not hasattr(cura.CuraVersion, "CuraSDKVersion"): # type: ignore
@ -499,17 +499,17 @@ class Toolbox(QObject, Extension):
local_version = Version(local_package["package_version"]) local_version = Version(local_package["package_version"])
remote_version = Version(remote_package["package_version"]) remote_version = Version(remote_package["package_version"])
if self._getSDKVersion() == "dev": if self._getSDKVersion() == "dev":
sdk_version = int(self._plugin_registry.APIVersion) sdk_version = self._plugin_registry.APIVersion
else: else:
sdk_version = int(self._getSDKVersion()) sdk_version = self._getSDKVersion()
can_upgrade = False can_upgrade = False
if remote_version > local_version: if remote_version > local_version:
can_upgrade = True can_upgrade = True
# A package with the same version can be built to have different SDK versions. So, for a package with the same # A package with the same version can be built to have different SDK versions. So, for a package with the same
# version, we also need to check if the current one has a lower SDK version. If so, this package should also # version, we also need to check if the current one has a lower SDK version. If so, this package should also
# be upgradable. # be upgradable.
elif remote_version == local_version and local_package.get("sdk_version", 0) < sdk_version: elif remote_version == local_version:
can_upgrade = True can_upgrade = local_package.get("sdk_version", 0) < remote_package.get("sdk_version", 0)
return can_upgrade return can_upgrade

View file

@ -13,14 +13,28 @@ import Cura 1.0 as Cura
Rectangle Rectangle
{ {
id: brand_section id: brand_section
property var expanded: base.collapsed_brands.indexOf(model.name) > -1
property var types_model: model.material_types property var sectionName: ""
property var elementsModel // This can be a MaterialTypesModel or GenericMaterialsModel or FavoriteMaterialsModel
property var hasMaterialTypes: true // It indicates wheather it has material types or not
property var expanded: materialList.expandedBrands.indexOf(sectionName) > -1
height: childrenRect.height height: childrenRect.height
width: parent.width width: parent.width
Rectangle Rectangle
{ {
id: brand_header_background id: brand_header_background
color: UM.Theme.getColor("favorites_header_bar") color:
{
if(!expanded && sectionName == materialList.currentBrand)
{
return UM.Theme.getColor("favorites_row_selected")
}
else
{
return UM.Theme.getColor("favorites_header_bar")
}
}
anchors.fill: brand_header anchors.fill: brand_header
} }
Row Row
@ -30,11 +44,11 @@ Rectangle
Label Label
{ {
id: brand_name id: brand_name
text: model.name text: sectionName
height: UM.Theme.getSize("favorites_row").height height: UM.Theme.getSize("favorites_row").height
width: parent.width - UM.Theme.getSize("favorites_button").width width: parent.width - UM.Theme.getSize("favorites_button").width
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
leftPadding: 4 leftPadding: (UM.Theme.getSize("default_margin").width / 2) | 0
} }
Button Button
{ {
@ -69,32 +83,68 @@ Rectangle
anchors.fill: brand_header anchors.fill: brand_header
onPressed: onPressed:
{ {
const i = base.collapsed_brands.indexOf(model.name) const i = materialList.expandedBrands.indexOf(sectionName)
if (i > -1) if (i > -1)
{ {
// Remove it // Remove it
base.collapsed_brands.splice(i, 1) materialList.expandedBrands.splice(i, 1)
brand_section.expanded = false brand_section.expanded = false
} }
else else
{ {
// Add it // Add it
base.collapsed_brands.push(model.name) materialList.expandedBrands.push(sectionName)
brand_section.expanded = true brand_section.expanded = true
} }
UM.Preferences.setValue("cura/expanded_brands", materialList.expandedBrands.join(";"));
} }
} }
Column Column
{ {
id: brandMaterialList
anchors.top: brand_header.bottom anchors.top: brand_header.bottom
width: parent.width width: parent.width
anchors.left: parent.left anchors.left: parent.left
height: brand_section.expanded ? childrenRect.height : 0 height: brand_section.expanded ? childrenRect.height : 0
visible: brand_section.expanded visible: brand_section.expanded
Repeater Repeater
{ {
model: types_model model: elementsModel
delegate: MaterialsTypeSection {} delegate: Loader
{
id: loader
width: parent.width
property var element: model
sourceComponent: hasMaterialTypes ? materialsTypeSection : materialSlot
}
}
}
Component
{
id: materialsTypeSection
MaterialsTypeSection
{
materialType: element
}
}
Component
{
id: materialSlot
MaterialsSlot
{
material: element
}
}
Connections
{
target: UM.Preferences
onPreferenceChanged:
{
expanded = materialList.expandedBrands.indexOf(sectionName) > -1
} }
} }
} }

View file

@ -13,21 +13,29 @@ Item
{ {
id: detailsPanel id: detailsPanel
property var currentItem: base.currentItem property var currentItem: null
onCurrentItemChanged: { updateMaterialPropertiesObject(currentItem) } onCurrentItemChanged:
{
// When the current item changes, the detail view needs to be updated
if (currentItem != null)
{
updateMaterialPropertiesObject()
materialDetailsView.currentMaterialNode = currentItem.container_node
}
}
function updateMaterialPropertiesObject( currentItem ) function updateMaterialPropertiesObject()
{ {
materialProperties.name = currentItem.name || "Unknown" materialProperties.name = currentItem.name || "Unknown"
materialProperties.guid = currentItem.GUID; materialProperties.guid = currentItem.GUID
materialProperties.container_id = currentItem.id materialProperties.container_id = currentItem.id
materialProperties.brand = currentItem.brand || "Unknown" materialProperties.brand = currentItem.brand || "Unknown"
materialProperties.material = currentItem.material || "Unknown" materialProperties.material = currentItem.material || "Unknown"
materialProperties.color_name = currentItem.color_name || "Yellow" materialProperties.color_name = currentItem.color_name || "Yellow"
materialProperties.color_code = currentItem.color_code || "yellow" materialProperties.color_code = currentItem.color_code || "yellow"
materialProperties.description = currentItem.description || "" materialProperties.description = currentItem.description || ""
materialProperties.adhesion_info = currentItem.adhesion_info || ""; materialProperties.adhesion_info = currentItem.adhesion_info || ""
materialProperties.density = currentItem.density || 0.0 materialProperties.density = currentItem.density || 0.0
materialProperties.diameter = currentItem.diameter || 0.0 materialProperties.diameter = currentItem.diameter || 0.0
materialProperties.approximate_diameter = currentItem.approximate_diameter || "0" materialProperties.approximate_diameter = currentItem.approximate_diameter || "0"
@ -62,13 +70,11 @@ Item
bottom: parent.bottom bottom: parent.bottom
} }
editingEnabled: base.currentItem != null && !base.currentItem.is_read_only editingEnabled: currentItem != null && !currentItem.is_read_only
properties: materialProperties properties: materialProperties
containerId: base.currentItem != null ? base.currentItem.id : "" containerId: currentItem != null ? currentItem.id : ""
currentMaterialNode: base.currentItem.container_node currentMaterialNode: currentItem.container_node
} }
QtObject QtObject

View file

@ -13,7 +13,6 @@ import Cura 1.0 as Cura
Item Item
{ {
id: materialList id: materialList
width: materialScrollView.width - 17
height: childrenRect.height height: childrenRect.height
// Children // Children
@ -21,179 +20,135 @@ Item
Cura.MaterialBrandsModel { id: materialsModel } Cura.MaterialBrandsModel { id: materialsModel }
Cura.FavoriteMaterialsModel { id: favoriteMaterialsModel } Cura.FavoriteMaterialsModel { id: favoriteMaterialsModel }
Cura.GenericMaterialsModel { id: genericMaterialsModel } Cura.GenericMaterialsModel { id: genericMaterialsModel }
Column
{
Rectangle
{
property var expanded: true
id: favorites_section property var currentType: null
height: childrenRect.height property var currentBrand: null
width: materialList.width property var expandedBrands: UM.Preferences.getValue("cura/expanded_brands").split(";")
Rectangle property var expandedTypes: UM.Preferences.getValue("cura/expanded_types").split(";")
{
id: favorites_header_background
color: UM.Theme.getColor("favorites_header_bar")
anchors.fill: favorites_header
}
Row
{
id: favorites_header
Label
{
id: favorites_name
text: "Favorites"
height: UM.Theme.getSize("favorites_row").height
width: materialList.width - UM.Theme.getSize("favorites_button").width
verticalAlignment: Text.AlignVCenter
leftPadding: 4
}
Button
{
text: ""
implicitWidth: UM.Theme.getSize("favorites_button").width
implicitHeight: UM.Theme.getSize("favorites_button").height
UM.RecolorImage {
anchors
{
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: "black"
source: favorites_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
}
style: ButtonStyle
{
background: Rectangle
{
anchors.fill: parent
color: "transparent"
}
}
}
}
MouseArea
{
anchors.fill: favorites_header
onPressed:
{
favorites_section.expanded = !favorites_section.expanded
}
}
Column
{
anchors.top: favorites_header.bottom
anchors.left: parent.left
width: materialList.width
height: favorites_section.expanded ? childrenRect.height : 0
visible: favorites_section.expanded
Repeater
{
model: favoriteMaterialsModel
delegate: MaterialsSlot {
material: model
}
}
}
}
Rectangle
{
property var expanded: base.collapsed_brands.indexOf("Generic") > -1
id: generic_section // Store information about which parts of the tree are expanded
height: childrenRect.height function persistExpandedCategories()
width: materialList.width
Rectangle
{ {
id: generic_header_background UM.Preferences.setValue("cura/expanded_brands", materialList.expandedBrands.join(";"))
color: UM.Theme.getColor("favorites_header_bar") UM.Preferences.setValue("cura/expanded_types", materialList.expandedTypes.join(";"))
anchors.fill: generic_header
} }
Row
// Expand the list of materials in order to select the current material
function expandActiveMaterial(search_root_id)
{ {
id: generic_header if (search_root_id == "")
Label
{ {
id: generic_name // When this happens it means that the information of one of the materials has changed, so the model
text: "Generic" // was updated and the list has to highlight the current item.
height: UM.Theme.getSize("favorites_row").height var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id
width: materialList.width - UM.Theme.getSize("favorites_button").width search_root_id = currentItemId
verticalAlignment: Text.AlignVCenter
leftPadding: 4
} }
Button for (var material_idx = 0; material_idx < genericMaterialsModel.rowCount(); material_idx++)
{ {
text: "" var material = genericMaterialsModel.getItem(material_idx)
implicitWidth: UM.Theme.getSize("favorites_button").width if (material.root_material_id == search_root_id)
implicitHeight: UM.Theme.getSize("favorites_button").height
UM.RecolorImage {
anchors
{ {
verticalCenter: parent.verticalCenter if (materialList.expandedBrands.indexOf("Generic") == -1)
horizontalCenter: parent.horizontalCenter
}
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: "black"
source: generic_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
}
style: ButtonStyle
{ {
background: Rectangle materialList.expandedBrands.push("Generic")
}
materialList.currentBrand = "Generic"
base.currentItem = material
persistExpandedCategories()
return true
}
}
for (var brand_idx = 0; brand_idx < materialsModel.rowCount(); brand_idx++)
{ {
anchors.fill: parent var brand = materialsModel.getItem(brand_idx)
color: "transparent" var types_model = brand.material_types
} for (var type_idx = 0; type_idx < types_model.rowCount(); type_idx++)
}
}
}
MouseArea
{ {
anchors.fill: generic_header var type = types_model.getItem(type_idx)
onPressed: var colors_model = type.colors
for (var material_idx = 0; material_idx < colors_model.rowCount(); material_idx++)
{ {
const i = base.collapsed_brands.indexOf("Generic") var material = colors_model.getItem(material_idx)
if (i > -1) if (material.root_material_id == search_root_id)
{ {
// Remove it if (materialList.expandedBrands.indexOf(brand.name) == -1)
base.collapsed_brands.splice(i, 1)
generic_section.expanded = false
}
else
{ {
// Add it materialList.expandedBrands.push(brand.name)
base.collapsed_brands.push("Generic") }
generic_section.expanded = true materialList.currentBrand = brand.name
if (materialList.expandedTypes.indexOf(brand.name + "_" + type.name) == -1)
{
materialList.expandedTypes.push(brand.name + "_" + type.name)
}
materialList.currentType = brand.name + "_" + type.name
base.currentItem = material
persistExpandedCategories()
return true
} }
} }
} }
}
return false
}
function updateAfterModelChanges()
{
var correctlyExpanded = materialList.expandActiveMaterial(base.newRootMaterialIdToSwitchTo)
if (correctlyExpanded)
{
if (base.toActivateNewMaterial)
{
var position = Cura.ExtruderManager.activeExtruderIndex
Cura.MachineManager.setMaterial(position, base.currentItem.container_node)
}
base.newRootMaterialIdToSwitchTo = ""
base.toActivateNewMaterial = false
}
}
Connections
{
target: materialsModel
onItemsChanged: updateAfterModelChanges()
}
Connections
{
target: genericMaterialsModel
onItemsChanged: updateAfterModelChanges()
}
Column Column
{ {
anchors.top: generic_header.bottom
width: materialList.width width: materialList.width
anchors.left: parent.left height: childrenRect.height
height: generic_section.expanded ? childrenRect.height : 0
visible: generic_section.expanded MaterialsBrandSection
{
id: favoriteSection
sectionName: "Favorites"
elementsModel: favoriteMaterialsModel
hasMaterialTypes: false
}
MaterialsBrandSection
{
id: genericSection
sectionName: "Generic"
elementsModel: genericMaterialsModel
hasMaterialTypes: false
}
Repeater Repeater
{ {
model: genericMaterialsModel
delegate: MaterialsSlot {
material: model
}
}
}
}
Repeater
{
id: brand_list
model: materialsModel model: materialsModel
delegate: MaterialsBrandSection {} delegate: MaterialsBrandSection
{
id: brandSection
sectionName: model.name
elementsModel: model.material_types
hasMaterialTypes: true
}
} }
} }
} }

View file

@ -17,96 +17,38 @@ Item
// Keep PreferencesDialog happy // Keep PreferencesDialog happy
property var resetEnabled: false property var resetEnabled: false
property var currentItem: null property var currentItem: null
property var hasCurrentItem: base.currentItem != null
property var isCurrentItemActivated: property var isCurrentItemActivated:
{ {
const extruder_position = Cura.ExtruderManager.activeExtruderIndex; if (!hasCurrentItem)
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; {
return base.currentItem.root_material_id == root_material_id; return false
}
const extruder_position = Cura.ExtruderManager.activeExtruderIndex
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]
return base.currentItem.root_material_id == root_material_id
} }
property string newRootMaterialIdToSwitchTo: "" property string newRootMaterialIdToSwitchTo: ""
property bool toActivateNewMaterial: false property bool toActivateNewMaterial: false
// TODO: Save these to preferences property var extruder_position: Cura.ExtruderManager.activeExtruderIndex
property var collapsed_brands: [] property var active_root_material_id: Cura.MachineManager.currentRootMaterialId[extruder_position]
property var collapsed_types: []
UM.I18nCatalog UM.I18nCatalog
{ {
id: catalog id: catalog
name: "cura" name: "cura"
} }
Cura.MaterialBrandsModel { id: materialsModel }
function findModelByRootId( search_root_id ) // When loaded, try to select the active material in the tree
{ Component.onCompleted: materialListView.expandActiveMaterial(active_root_material_id)
for (var i = 0; i < materialsModel.rowCount(); i++)
{
var types_model = materialsModel.getItem(i).material_types;
for (var j = 0; j < types_model.rowCount(); j++)
{
var colors_model = types_model.getItem(j).colors;
for (var k = 0; k < colors_model.rowCount(); k++)
{
var material = colors_model.getItem(k);
if (material.root_material_id == search_root_id)
{
return material
}
}
}
}
}
Component.onCompleted:
{
// Select the activated material when this page shows up
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
const active_root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
console.log("goign to search for", active_root_material_id)
base.currentItem = findModelByRootId(active_root_material_id)
}
onCurrentItemChanged: { MaterialsDetailsPanel.currentItem = currentItem } // Every time the selected item has changed, notify to the details panel
Connections onCurrentItemChanged:
{ {
target: materialsModel forceActiveFocus()
onItemsChanged: materialDetailsPanel.currentItem = currentItem
{
var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id;
var position = Cura.ExtruderManager.activeExtruderIndex;
// try to pick the currently selected item; it may have been moved
if (base.newRootMaterialIdToSwitchTo == "")
{
base.newRootMaterialIdToSwitchTo = currentItemId;
}
for (var idx = 0; idx < materialsModel.rowCount(); ++idx)
{
var item = materialsModel.getItem(idx);
if (item.root_material_id == base.newRootMaterialIdToSwitchTo)
{
// Switch to the newly created profile if needed
materialListView.currentIndex = idx;
materialListView.activateDetailsWithIndex(materialListView.currentIndex);
if (base.toActivateNewMaterial)
{
Cura.MachineManager.setMaterial(position, item.container_node);
}
base.newRootMaterialIdToSwitchTo = "";
base.toActivateNewMaterial = false;
return
}
}
materialListView.currentIndex = 0;
materialListView.activateDetailsWithIndex(materialListView.currentIndex);
if (base.toActivateNewMaterial)
{
Cura.MachineManager.setMaterial(position, materialsModel.getItem(0).container_node);
}
base.newRootMaterialIdToSwitchTo = "";
base.toActivateNewMaterial = false;
}
} }
// Main layout // Main layout
@ -146,8 +88,10 @@ Item
{ {
forceActiveFocus() forceActiveFocus()
const extruder_position = Cura.ExtruderManager.activeExtruderIndex; // Set the current material as the one to be activated (needed to force the UI update)
Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node); base.newRootMaterialIdToSwitchTo = base.currentItem.root_material_id
const extruder_position = Cura.ExtruderManager.activeExtruderIndex
Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node)
} }
} }
@ -214,7 +158,7 @@ Item
forceActiveFocus(); forceActiveFocus();
exportMaterialDialog.open(); exportMaterialDialog.open();
} }
enabled: currentItem != null enabled: base.hasCurrentItem
} }
} }
@ -285,15 +229,20 @@ Item
color: palette.light color: palette.light
} }
width: true ? (parent.width * 0.4) | 0 : parent.width width: (parent.width * 0.4) | 0
frameVisible: true frameVisible: true
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
MaterialsList {} MaterialsList
{
id: materialListView
width: materialScrollView.viewport.width
}
} }
MaterialsDetailsPanel MaterialsDetailsPanel
{ {
id: materialDetailsPanel
anchors anchors
{ {
left: materialScrollView.right left: materialScrollView.right
@ -316,6 +265,8 @@ Item
modality: Qt.ApplicationModal modality: Qt.ApplicationModal
onYes: onYes:
{ {
// Set the active material as the fallback. It will be selected when the current material is deleted
base.newRootMaterialIdToSwitchTo = base.active_root_material_id
base.materialManager.removeMaterial(base.currentItem.container_node); base.materialManager.removeMaterial(base.currentItem.container_node);
} }
} }

View file

@ -12,47 +12,48 @@ import Cura 1.0 as Cura
Rectangle Rectangle
{ {
id: material_slot id: materialSlot
property var material property var material: null
property var hovered: false property var hovered: false
property var is_favorite: material.is_favorite property var is_favorite: material != null ? material.is_favorite : false
height: UM.Theme.getSize("favorites_row").height height: UM.Theme.getSize("favorites_row").height
width: parent.width width: parent.width
color: base.currentItem == model ? UM.Theme.getColor("favorites_row_selected") : "transparent" color: material != null ? (base.currentItem.root_material_id == material.root_material_id ? UM.Theme.getColor("favorites_row_selected") : "transparent") : "transparent"
Item
{
height: parent.height
width: parent.width
Rectangle Rectangle
{ {
id: swatch id: swatch
color: material.color_code color: material != null ? material.color_code : "transparent"
border.width: UM.Theme.getSize("default_lining").width border.width: UM.Theme.getSize("default_lining").width
border.color: "black" border.color: "black"
width: UM.Theme.getSize("favorites_button_icon").width width: UM.Theme.getSize("favorites_button_icon").width
height: UM.Theme.getSize("favorites_button_icon").height height: UM.Theme.getSize("favorites_button_icon").height
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: materialSlot.verticalCenter
anchors.left: parent.left anchors.left: materialSlot.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.leftMargin: UM.Theme.getSize("default_margin").width
} }
Label Label
{ {
text: material.brand + " " + material.name text: material != null ? material.brand + " " + material.name : ""
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
height: parent.height height: parent.height
anchors.left: swatch.right anchors.left: swatch.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: materialSlot.verticalCenter
anchors.leftMargin: UM.Theme.getSize("narrow_margin").width anchors.leftMargin: UM.Theme.getSize("narrow_margin").width
} }
MouseArea MouseArea
{ {
anchors.fill: parent anchors.fill: parent
onClicked: { base.currentItem = material } onClicked:
{
materialList.currentBrand = material.brand
materialList.currentType = material.brand + "_" + material.material
base.currentItem = material
}
hoverEnabled: true hoverEnabled: true
onEntered: { material_slot.hovered = true } onEntered: { materialSlot.hovered = true }
onExited: { material_slot.hovered = false } onExited: { materialSlot.hovered = false }
} }
Button Button
{ {
@ -60,21 +61,21 @@ Rectangle
text: "" text: ""
implicitWidth: UM.Theme.getSize("favorites_button").width implicitWidth: UM.Theme.getSize("favorites_button").width
implicitHeight: UM.Theme.getSize("favorites_button").height implicitHeight: UM.Theme.getSize("favorites_button").height
visible: material_slot.hovered || material_slot.is_favorite || favorite_button.hovered visible: materialSlot.hovered || materialSlot.is_favorite || favorite_button.hovered
anchors anchors
{ {
right: parent.right right: materialSlot.right
verticalCenter: parent.verticalCenter verticalCenter: materialSlot.verticalCenter
} }
onClicked: onClicked:
{ {
if (material_slot.is_favorite) { if (materialSlot.is_favorite) {
base.materialManager.removeFavorite(material.root_material_id) base.materialManager.removeFavorite(material.root_material_id)
material_slot.is_favorite = false materialSlot.is_favorite = false
return return
} }
base.materialManager.addFavorite(material.root_material_id) base.materialManager.addFavorite(material.root_material_id)
material_slot.is_favorite = true materialSlot.is_favorite = true
return return
} }
style: ButtonStyle style: ButtonStyle
@ -88,8 +89,8 @@ Rectangle
UM.RecolorImage { UM.RecolorImage {
anchors anchors
{ {
verticalCenter: parent.verticalCenter verticalCenter: favorite_button.verticalCenter
horizontalCenter: parent.horizontalCenter horizontalCenter: favorite_button.horizontalCenter
} }
width: UM.Theme.getSize("favorites_button_icon").width width: UM.Theme.getSize("favorites_button_icon").width
height: UM.Theme.getSize("favorites_button_icon").height height: UM.Theme.getSize("favorites_button_icon").height
@ -103,7 +104,7 @@ Rectangle
} }
else else
{ {
if (material_slot.is_favorite) if (materialSlot.is_favorite)
{ {
return UM.Theme.getColor("primary") return UM.Theme.getColor("primary")
} }
@ -113,8 +114,7 @@ Rectangle
} }
} }
} }
source: material_slot.is_favorite ? UM.Theme.getIcon("favorites_star_full") : UM.Theme.getIcon("favorites_star_empty") source: materialSlot.is_favorite ? UM.Theme.getIcon("favorites_star_full") : UM.Theme.getIcon("favorites_star_empty")
}
} }
} }
} }

View file

@ -13,14 +13,32 @@ import Cura 1.0 as Cura
Rectangle Rectangle
{ {
id: material_type_section id: material_type_section
property var expanded: base.collapsed_types.indexOf(model.brand + "_" + model.name) > -1 property var materialType
property var colors_model: model.colors property var expanded: materialList.expandedTypes.indexOf(materialType.brand + "_" + materialType.name) > -1
property var colorsModel: materialType.colors
height: childrenRect.height height: childrenRect.height
width: parent.width width: parent.width
Rectangle Rectangle
{ {
id: material_type_header_background id: material_type_header_background
color: UM.Theme.getColor("lining") color:
{
if(!expanded && materialType.brand + "_" + materialType.name == materialList.currentType)
{
return UM.Theme.getColor("favorites_row_selected")
}
else
{
return "transparent"
}
}
width: parent.width
height: material_type_header.height
}
Rectangle
{
id: material_type_header_border
color: UM.Theme.getColor("favorites_header_bar")
anchors.bottom: material_type_header.bottom anchors.bottom: material_type_header.bottom
anchors.left: material_type_header.left anchors.left: material_type_header.left
height: UM.Theme.getSize("default_lining").height height: UM.Theme.getSize("default_lining").height
@ -29,17 +47,17 @@ Rectangle
Row Row
{ {
id: material_type_header id: material_type_header
width: parent.width - 8 width: parent.width
leftPadding: UM.Theme.getSize("default_margin").width
anchors anchors
{ {
left: parent.left left: parent.left
leftMargin: 8
} }
Label Label
{ {
text: model.name text: materialType.name
height: UM.Theme.getSize("favorites_row").height height: UM.Theme.getSize("favorites_row").height
width: parent.width - UM.Theme.getSize("favorites_button").width width: parent.width - parent.leftPadding - UM.Theme.getSize("favorites_button").width
id: material_type_name id: material_type_name
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
@ -76,19 +94,21 @@ Rectangle
anchors.fill: material_type_header anchors.fill: material_type_header
onPressed: onPressed:
{ {
const i = base.collapsed_types.indexOf(model.brand + "_" + model.name) const identifier = materialType.brand + "_" + materialType.name;
const i = materialList.expandedTypes.indexOf(identifier)
if (i > -1) if (i > -1)
{ {
// Remove it // Remove it
base.collapsed_types.splice(i, 1) materialList.expandedTypes.splice(i, 1)
material_type_section.expanded = false material_type_section.expanded = false
} }
else else
{ {
// Add it // Add it
base.collapsed_types.push(model.brand + "_" + model.name) materialList.expandedTypes.push(identifier)
material_type_section.expanded = true material_type_section.expanded = true
} }
UM.Preferences.setValue("cura/expanded_types", materialList.expandedTypes.join(";"));
} }
} }
Column Column
@ -97,13 +117,22 @@ Rectangle
visible: material_type_section.expanded visible: material_type_section.expanded
width: parent.width width: parent.width
anchors.top: material_type_header.bottom anchors.top: material_type_header.bottom
anchors.left: parent.left
Repeater Repeater
{ {
model: colors_model model: colorsModel
delegate: MaterialsSlot { delegate: MaterialsSlot
{
material: model material: model
} }
} }
} }
Connections
{
target: UM.Preferences
onPreferenceChanged:
{
expanded = materialList.expandedTypes.indexOf(materialType.brand + "_" + materialType.name) > -1
}
}
} }

View file

@ -40,7 +40,7 @@ TabView
{ {
return "" return ""
} }
var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentItem.container_node, true); var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentMaterialNode, true);
if (linkedMaterials.length == 0) if (linkedMaterials.length == 0)
{ {
return "" return ""
@ -191,6 +191,7 @@ TabView
ReadOnlyTextField ReadOnlyTextField
{ {
id: colorLabel; id: colorLabel;
width: parent.width - colorSelector.width - parent.spacing
text: properties.color_name; text: properties.color_name;
readOnly: !base.editingEnabled readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text) onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
@ -567,25 +568,25 @@ TabView
// don't change when new name is the same // don't change when new name is the same
if (old_name == new_name) if (old_name == new_name)
{ {
return; return
} }
// update the values // update the values
base.materialManager.setMaterialName(base.currentMaterialNode, new_name); base.materialManager.setMaterialName(base.currentMaterialNode, new_name)
materialProperties.name = new_name; properties.name = new_name
} }
// update the type of the material // update the type of the material
function updateMaterialType (old_type, new_type) function updateMaterialType(old_type, new_type)
{ {
base.setMetaDataEntry("material", old_type, new_type); base.setMetaDataEntry("material", old_type, new_type)
materialProperties.material= new_type; properties.material = new_type
} }
// update the brand of the material // update the brand of the material
function updateMaterialBrand (old_brand, new_brand) function updateMaterialBrand(old_brand, new_brand)
{ {
base.setMetaDataEntry("brand", old_brand, new_brand); base.setMetaDataEntry("brand", old_brand, new_brand)
materialProperties.brand = new_brand; properties.brand = new_brand
} }
} }