From 993ce46fcc93c815cdb63a266cf7b8d143168a08 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 23 May 2024 12:10:47 +0500 Subject: [PATCH] improve ux for assigning cost item to product types 1) also consider active object as selected when assigning / unassigning cost item to product types. Typically types are hidden and if you select some type in outliner it will become active but still not selected. Now it will be possible to add this active object without unhiding the entire Types collection. 2) info messages to make UI more responsive --- .../blenderbim/bim/module/cost/operator.py | 18 ++++++++---- src/blenderbim/blenderbim/core/cost.py | 28 ++++++++++++++----- src/blenderbim/blenderbim/tool/spatial.py | 2 +- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/cost/operator.py b/src/blenderbim/blenderbim/bim/module/cost/operator.py index 6aae74d68c..3a1a96f76f 100644 --- a/src/blenderbim/blenderbim/bim/module/cost/operator.py +++ b/src/blenderbim/blenderbim/bim/module/cost/operator.py @@ -224,35 +224,39 @@ class EditCostItem(bpy.types.Operator, tool.Ifc.Operator): class AssignCostItemType(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.assign_cost_item_type" bl_label = "Assign Cost Item To Product Types" + bl_description = "Assign cost item to currently selected or active product types" bl_options = {"REGISTER", "UNDO"} cost_item: bpy.props.IntProperty() prop_name: bpy.props.StringProperty() def _execute(self, context): - core.assign_cost_item_type( + product_types = core.assign_cost_item_type( tool.Ifc, tool.Cost, tool.Spatial, cost_item=tool.Ifc.get().by_id(self.cost_item), prop_name=self.prop_name, # TODO: REVIEW PROP_NAME USABILITY ) + self.report({"INFO"}, f"Cost item was assigned to {len(product_types)} product types.") class UnassignCostItemType(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.unassign_cost_item_type" bl_label = "Unassign Cost Item Type" + bl_description = "Unassign cost item from currently selected or active product types" bl_options = {"REGISTER", "UNDO"} cost_item: bpy.props.IntProperty() related_object: bpy.props.IntProperty() def _execute(self, context): - core.unassign_cost_item_type( + product_types = core.unassign_cost_item_type( tool.Ifc, tool.Cost, tool.Spatial, cost_item=tool.Ifc.get().by_id(self.cost_item), - product_types=[tool.Ifc.get().by_id(self.related_object)] if self.related_object else [], + product_types=[tool.Ifc.get().by_id(self.related_object)] if self.related_object else None, ) + self.report({"INFO"}, f"Cost item was unassigned from {len(product_types)} product types.") return {"FINISHED"} @@ -287,9 +291,11 @@ class UnassignCostItemQuantity(bpy.types.Operator, tool.Ifc.Operator): tool.Ifc, tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item), - products=[tool.Ifc.get().by_id(self.related_object)] - if self.related_object - else tool.Spatial.get_selected_products(), + products=( + [tool.Ifc.get().by_id(self.related_object)] + if self.related_object + else tool.Spatial.get_selected_products() + ), ) diff --git a/src/blenderbim/blenderbim/core/cost.py b/src/blenderbim/blenderbim/core/cost.py index 0859ed59b1..9d4c4048f1 100644 --- a/src/blenderbim/blenderbim/core/cost.py +++ b/src/blenderbim/blenderbim/core/cost.py @@ -17,7 +17,7 @@ # along with BlenderBIM Add-on. If not, see . from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Union if TYPE_CHECKING: import bpy @@ -111,25 +111,39 @@ def edit_cost_item(ifc: tool.Ifc, cost: tool.Cost): def assign_cost_item_type( ifc: tool.Ifc, cost: tool.Cost, spatial: tool.Spatial, cost_item: ifcopenshell.entity_instance, prop_name -): - product_types = spatial.get_selected_product_types() - [ +) -> list[ifcopenshell.entity_instance]: + """ + Returns: + List of found product types. + """ + product_types = list(spatial.get_selected_product_types()) + rels = [ ifc.run("control.assign_control", relating_control=cost_item, related_object=product_type) for product_type in product_types ] cost.load_cost_item_types(cost_item) + return product_types def unassign_cost_item_type( - ifc: tool.Ifc, cost: tool.Cost, spatial: tool.Spatial, cost_item: ifcopenshell.entity_instance, product_types -): + ifc: tool.Ifc, + cost: tool.Cost, + spatial: tool.Spatial, + cost_item: ifcopenshell.entity_instance, + product_types: Optional[list[ifcopenshell.entity_instance]] = None, +) -> list[ifcopenshell.entity_instance]: + """ + Returns: + List of found product types. + """ if not product_types: - product_types = spatial.get_selected_product_types() + product_types = list(spatial.get_selected_product_types()) [ ifc.run("control.unassign_control", relating_control=cost_item, related_object=product_type) for product_type in product_types ] cost.load_cost_item_types(cost_item) + return product_types def load_cost_item_types(cost: tool.Cost): diff --git a/src/blenderbim/blenderbim/tool/spatial.py b/src/blenderbim/blenderbim/tool/spatial.py index 101d17e454..057b0eabf1 100644 --- a/src/blenderbim/blenderbim/tool/spatial.py +++ b/src/blenderbim/blenderbim/tool/spatial.py @@ -196,7 +196,7 @@ class Spatial(blenderbim.core.tool.Spatial): @classmethod def get_selected_product_types(cls) -> Generator[ifcopenshell.entity_instance, None, None]: - for obj in bpy.context.selected_objects: + for obj in tool.Blender.get_selected_objects(): entity = tool.Ifc.get_entity(obj) if entity and entity.is_a("IfcTypeProduct"): yield entity