From 16b1b4e7b175a314d0324613127e47f0c231c052 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Tue, 21 Jul 2026 17:11:56 +0300 Subject: [PATCH] Bonsai: refresh the UI after renaming a material theoryshaw tested #8843 and asked for the new name to show up right away instead of needing a manual refresh. The Object Material panel and the scene Materials list both already re-read live IFC data on their next draw (tool.Ifc.Operator purges those caches after every IFC-mutating operator), so the button text was correct on the next redraw. What was missing was the redraw itself: the material name is a plain button label, not an RNA property Blender tracks, so nothing told the Properties editor to repaint after the rename dialog closed. Tag every area for redraw once the rename completes, the same pattern used elsewhere in Bonsai for popup-triggered edits that need an immediate repaint. Also adds core-layer test coverage for rename_material, which had none. Generated with the assistance of an AI coding tool. --- src/bonsai/bonsai/bim/module/material/operator.py | 3 +++ src/bonsai/test/core/test_material.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/bonsai/bonsai/bim/module/material/operator.py b/src/bonsai/bonsai/bim/module/material/operator.py index b2ab1cfa06..d744ea5780 100644 --- a/src/bonsai/bonsai/bim/module/material/operator.py +++ b/src/bonsai/bonsai/bim/module/material/operator.py @@ -120,6 +120,9 @@ class RenameMaterial(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): core.rename_material(tool.Ifc, tool.Material, material=tool.Ifc.get().by_id(self.material), name=self.name) + if screen := context.screen: + for area in screen.areas: + area.tag_redraw() class DisableEditingMaterial(bpy.types.Operator): diff --git a/src/bonsai/test/core/test_material.py b/src/bonsai/test/core/test_material.py index a2cbf8c433..ba83e9884d 100644 --- a/src/bonsai/test/core/test_material.py +++ b/src/bonsai/test/core/test_material.py @@ -93,6 +93,20 @@ class TestRemoveMaterialSet: subject.remove_material_set(ifc, material, material="material") +class TestRenameMaterial: + def test_renaming_a_material(self, ifc, material): + ifc.run("material.edit_material", material="material", attributes={"Name": "name"}).should_be_called() + material.is_editing_materials().should_be_called().will_return(False) + subject.rename_material(ifc, material, material="material", name="name") + + def test_renaming_a_material_and_reloading_imported_materials(self, ifc, material): + ifc.run("material.edit_material", material="material", attributes={"Name": "name"}).should_be_called() + material.is_editing_materials().should_be_called().will_return(True) + material.get_active_material_type().should_be_called().will_return("material_type") + material.import_material_definitions("material_type").should_be_called() + subject.rename_material(ifc, material, material="material", name="name") + + class TestLoadMaterials: def test_run(self, material): material.import_material_definitions("material_type").should_be_called()