From c08cc58904983093f0062620253ce25338c8ca8c Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 7 Nov 2025 19:13:14 +0500 Subject: [PATCH] Blender 5.0 - fix opening Web UI In Blender 5.0 some theme attributes were removed and moved to other places and code broke. In the commit I've also switched the code to less dynamic approach, so static type checker could caught potential errors. --- src/bonsai/bonsai/tool/web.py | 74 ++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/bonsai/bonsai/tool/web.py b/src/bonsai/bonsai/tool/web.py index 66847f0c03..7ab178bde7 100644 --- a/src/bonsai/bonsai/tool/web.py +++ b/src/bonsai/bonsai/tool/web.py @@ -28,7 +28,8 @@ import bonsai.tool as tool import ifcopenshell.api.sequence import ifcopenshell.api.classification import ifcopenshell.api.cost -from typing import Any, Optional, TYPE_CHECKING +from typing import Any, Optional, TYPE_CHECKING, Union +from mathutils import Color import time import socket import sys @@ -790,8 +791,8 @@ class Web(bonsai.core.tool.Web): calculates the mixed colors, and sends the theme data to the Web UI. """ - def get_color(theme, attribute) -> tuple[Any, ...]: - return tuple(getattr(theme, attribute)[:]) + def to_tuple(theme: Union[Color, bpy.types.bpy_prop_array[float]]) -> tuple[float, ...]: + return tuple(theme[:]) def mix_colors(color1, color2): alpha1 = color1[3] * 255 if len(color1) > 3 else 255 @@ -803,33 +804,50 @@ class Web(bonsai.core.tool.Web): blue = (color1[2] * (255 - alpha2) + color2[2] * alpha2) / 255 return red, green, blue, alpha / 255 - prefs = bpy.context.preferences.themes[0].preferences.space - panel = prefs.panelcolors - view_3d = bpy.context.preferences.themes[0].view_3d - top_bar = bpy.context.preferences.themes[0].topbar.space - info = bpy.context.preferences.themes[0].info - outliner = bpy.context.preferences.themes[0].outliner - ui = bpy.context.preferences.themes[0].user_interface + assert (blender_preferences := bpy.context.preferences) + blender_theme = blender_preferences.themes[0] + prefs = blender_theme.preferences.space + + if tool.Blender.BLENDER_5 or TYPE_CHECKING: + theme_ui = blender_theme.user_interface + theme_regions = blender_theme.regions + panel_header, panel_back, panel_sub_back = ( + theme_ui.panel_header, + theme_ui.panel_back, + theme_ui.panel_sub_back, + ) + tab_back, tab_outline = theme_regions.sidebars.tab_back, theme_ui.wcol_tab.outline + else: + # Removed in Blender 5.0. + panel = prefs.panelcolors + tab_back, tab_outline = prefs.tab_back, prefs.tab_outline + panel_header, panel_back, panel_sub_back = panel.header, panel.back, panel.sub_back + + view_3d = blender_theme.view_3d + top_bar = blender_theme.topbar.space + info = blender_theme.info + outliner = blender_theme.outliner + ui = blender_theme.user_interface theme = { - "window_background": get_color(prefs, "back"), - "text": get_color(prefs, "text"), - "tab_background": get_color(prefs, "tab_back"), - "tab_outline": get_color(prefs, "tab_outline"), - "panel_header": get_color(panel, "header"), - "panel_background": mix_colors(get_color(panel, "back"), get_color(panel, "sub_back")), - "top_bar_header": get_color(top_bar, "header"), - "top_bar_header_text": get_color(top_bar, "header_text"), - "active_object": get_color(view_3d, "object_active"), - "selected_object": get_color(view_3d, "object_selected"), - "info_warning": get_color(info, "info_warning_text"), - "odd_row": get_color(outliner.space, "back"), - "even_row": mix_colors(get_color(outliner.space, "back"), get_color(outliner, "row_alternate")), - "active_highlight": get_color(outliner, "active"), - "active_text_highlight": get_color(outliner, "active_object"), - "button_background": get_color(ui.wcol_tool, "inner"), - "button_test": get_color(ui.wcol_tool, "text"), - "button_border": get_color(ui.wcol_tool, "outline"), + "window_background": prefs.back[:], + "text": to_tuple(prefs.text), + "tab_background": to_tuple(tab_back), + "tab_outline": to_tuple(tab_outline), + "panel_header": to_tuple(panel_header), + "panel_background": mix_colors(to_tuple(panel_back), to_tuple(panel_sub_back)), + "top_bar_header": to_tuple(top_bar.header), + "top_bar_header_text": to_tuple(top_bar.header_text), + "active_object": to_tuple(view_3d.object_active), + "selected_object": to_tuple(view_3d.object_selected), + "info_warning": to_tuple(info.info_warning_text), + "odd_row": to_tuple(outliner.space.back), + "even_row": mix_colors(to_tuple(outliner.space.back), to_tuple(outliner.row_alternate)), + "active_highlight": to_tuple(outliner.active), + "active_text_highlight": to_tuple(outliner.active_object), + "button_background": to_tuple(ui.wcol_tool.inner), + "button_test": to_tuple(ui.wcol_tool.text), + "button_border": to_tuple(ui.wcol_tool.outline), } cls.send_webui_data(theme, "theme", "theme_data", use_web_data=False)