diff --git a/multi_user/__init__.py b/multi_user/__init__.py index 98a8d95..85fb157 100644 --- a/multi_user/__init__.py +++ b/multi_user/__init__.py @@ -19,7 +19,7 @@ bl_info = { "name": "Multi-User", "author": "Swann Martinez", - "version": (0, 1, 0), + "version": (0, 1, 1), "description": "Enable real-time collaborative workflow inside blender", "blender": (2, 82, 0), "location": "3D View > Sidebar > Multi-User tab", diff --git a/multi_user/delayable.py b/multi_user/delayable.py index 32cf6e4..9db1711 100644 --- a/multi_user/delayable.py +++ b/multi_user/delayable.py @@ -307,6 +307,9 @@ class SessionUserSync(Timer): for index, user in enumerate(ui_users): if user.username not in session_users.keys(): ui_users.remove(index) + renderer.remove_widget(f"{user}_cam") + renderer.remove_widget(f"{user}_select") + renderer.remove_widget(f"{user}_name") break for user in session_users: @@ -315,9 +318,9 @@ class SessionUserSync(Timer): new_key.name = user new_key.username = user if user != self.settings.username: - renderer.add_widget(UserFrustumWidget(user)) - renderer.add_widget(UserSelectionWidget(user)) - renderer.add_widget(UserNameWidget(user)) + renderer.add_widget(f"{user}_cam", UserFrustumWidget(user)) + renderer.add_widget(f"{user}_select", UserSelectionWidget(user)) + renderer.add_widget(f"{user}_name", UserNameWidget(user)) class MainThreadExecutor(Timer): diff --git a/multi_user/operators.py b/multi_user/operators.py index aa65cd9..e3ba8f5 100644 --- a/multi_user/operators.py +++ b/multi_user/operators.py @@ -107,9 +107,6 @@ def on_connection_end(): bpy.app.handlers.depsgraph_update_post.remove( depsgraph_evaluation) - renderer.clear_widgets() - refresh_3d_view() - # Step 3: remove file handled logger = logging.getLogger() for handler in logger.handlers: @@ -268,8 +265,6 @@ class SessionStartOperator(bpy.types.Operator): bpy.ops.session.apply_armature_operator() - renderer.add_widget(SessionStatusWidget()) - self.report( {'INFO'}, f"connecting to tcp://{settings.ip}:{settings.port}") @@ -742,6 +737,7 @@ def depsgraph_evaluation(scene): def register(): from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/multi_user/presence.py b/multi_user/presence.py index 0901686..65791f7 100644 --- a/multi_user/presence.py +++ b/multi_user/presence.py @@ -191,12 +191,20 @@ def get_view_matrix() -> list: class Widget(object): - draw_type = 'POST_VIEW' + """ Base class to define an interface element + """ + draw_type: str = 'POST_VIEW' # Draw event type def poll(self) -> bool: + """Test if the widget can be drawn or not + + :return: bool + """ return True def draw(self): + """How to draw the widget + """ raise NotImplementedError() @@ -376,12 +384,13 @@ class UserNameWidget(Widget): class SessionStatusWidget(Widget): draw_type = 'POST_PIXEL' - def __init__(self): - self.settings = bpy.context.window_manager.session + @property + def settings(self): + return getattr(bpy.context.window_manager, 'session', None) def poll(self): - return self.settings.presence_show_session_status and \ - self.settings.enable_presence + return self.settings and self.settings.presence_show_session_status and \ + self.settings.enable_presence def draw(self): color = [1, 1, 0, 1] @@ -403,13 +412,16 @@ class DrawFactory(object): def __init__(self): self.post_view_handle = None self.post_pixel_handle = None - self.widgets = [] + self.widgets = {} - def add_widget(self, widget: Widget): - self.widgets.append(widget) + def add_widget(self, name:str, widget: Widget): + self.widgets[name] = widget - def remove_widget(self, widget): - self.widgets.remove(widget) + def remove_widget(self, name: str): + if name in self.widgets: + del self.widgets[name] + else: + logging.info("Widget {name} not existing") def clear_widgets(self): self.widgets.clear() @@ -441,7 +453,7 @@ class DrawFactory(object): def post_view_callback(self): try: - for widget in self.widgets: + for widget in self.widgets.values(): if widget.draw_type == 'POST_VIEW' and widget.poll(): widget.draw() except Exception as e: @@ -450,7 +462,7 @@ class DrawFactory(object): def post_pixel_callback(self): try: - for widget in self.widgets: + for widget in self.widgets.values(): if widget.draw_type == 'POST_PIXEL' and widget.poll(): widget.draw() except Exception as e: @@ -465,6 +477,10 @@ this.renderer = DrawFactory() def register(): this.renderer.register_handlers() + renderer.add_widget("session_status", SessionStatusWidget()) + def unregister(): this.renderer.unregister_handlers() + + this.renderer.clear_widgets() \ No newline at end of file