diff --git a/multi_user/icons/server_offline.png b/multi_user/icons/server_offline.png new file mode 100644 index 0000000..e636630 Binary files /dev/null and b/multi_user/icons/server_offline.png differ diff --git a/multi_user/icons/server_online.png b/multi_user/icons/server_online.png new file mode 100644 index 0000000..e7e86aa Binary files /dev/null and b/multi_user/icons/server_online.png differ diff --git a/multi_user/operators.py b/multi_user/operators.py index bb21f7b..c78c0bd 100644 --- a/multi_user/operators.py +++ b/multi_user/operators.py @@ -20,6 +20,7 @@ import asyncio import copy import gzip import logging +from multi_user.preferences import ServerPreset import os import queue import random @@ -57,7 +58,7 @@ from replication.repository import Repository from . import bl_types, environment, shared_data, timers, ui, utils from .handlers import on_scene_update, sanitize_deps_graph -from .presence import SessionStatusWidget, renderer, view3d_find +from .presence import SessionStatusWidget, renderer, view3d_find, refresh_sidebar_view from .timers import registry background_execution_queue = Queue() @@ -928,20 +929,26 @@ class SessionPresetServerAdd(bpy.types.Operator): bl_description = "add a server to the server preset list" bl_options = {"REGISTER"} - target_server_name: bpy.props.StringProperty(default="None") + server_name: bpy.props.StringProperty(default="") + server_ip: bpy.props.StringProperty(default="127.0.0.1") + server_port: bpy.props.IntProperty(default=5555) + use_server_password: bpy.props.BoolProperty(default=False) + server_server_password: bpy.props.StringProperty(default="", subtype = "PASSWORD") + use_admin_password: bpy.props.BoolProperty(default=False) + server_admin_password: bpy.props.StringProperty(default="", subtype = "PASSWORD") @classmethod def poll(cls, context): return True def invoke(self, context, event): - settings = utils.get_preferences() - - settings.server_name = "" - settings.ip = "127.0.0.1" - settings.port = 5555 - settings.server_password = "" - settings.admin_password = "" + self.server_name = "" + self.server_ip = "127.0.0.1" + self.server_port = 5555 + self.use_server_password = False + self.server_server_password = "" + self.use_admin_password = False + self.server_admin_password = "" assert(context) return context.window_manager.invoke_props_dialog(self) @@ -951,34 +958,45 @@ class SessionPresetServerAdd(bpy.types.Operator): settings = utils.get_preferences() row = layout.row() - row.prop(settings, "server_name", text="Server name") + row.prop(self, "server_name", text="Server name") row = layout.row(align = True) - row.prop(settings, "ip", text="IP+port") - row.prop(settings, "port", text="") + row.prop(self, "server_ip", text="IP+port") + row.prop(self, "server_port", text="") row = layout.row() - row.prop(settings, "server_password", text="Server password") + col = row.column() + col.prop(self, "use_server_password", text="Server password:") + col = row.column() + col.enabled = True if self.use_server_password else False + col.prop(self, "server_server_password", text="") row = layout.row() - row.prop(settings, "admin_password", text="Admin password") + col = row.column() + col.prop(self, "use_admin_password", text="Admin password:") + col = row.column() + col.enabled = True if self.use_admin_password else False + col.prop(self, "server_admin_password", text="") def execute(self, context): assert(context) settings = utils.get_preferences() - - existing_preset = settings.server_preset.get(settings.server_name) + existing_preset = settings.get_server_preset(self.server_name) new_server = existing_preset if existing_preset else settings.server_preset.add() new_server.name = str(uuid4()) - new_server.server_name = settings.server_name - new_server.server_ip = settings.ip - new_server.server_port = settings.port - new_server.server_server_password = settings.server_password - new_server.server_admin_password = settings.admin_password + new_server.server_name = self.server_name + new_server.server_ip = self.server_ip + new_server.server_port = self.server_port + new_server.use_server_password = self.use_server_password + new_server.server_server_password = self.server_server_password + new_server.use_admin_password = self.use_admin_password + new_server.server_admin_password = self.server_admin_password + + refresh_sidebar_view() if new_server == existing_preset : - self.report({'INFO'}, "Server '" + settings.server_name + "' override") + self.report({'INFO'}, "Server '" + self.server_name + "' override") else : - self.report({'INFO'}, "New '" + settings.server_name + "' server preset") + self.report({'INFO'}, "New '" + self.server_name + "' server preset") return {'FINISHED'} @@ -1020,9 +1038,17 @@ class SessionPresetServerEdit(bpy.types.Operator): row.prop(settings, "ip", text="IP+port") row.prop(settings, "port", text="") row = layout.row() - row.prop(settings, "server_password", text="Server password") + col = row.column() + col.prop(settings, "use_server_password", text="Server password:") + col = row.column() + col.enabled = True if settings.use_server_password else False + col.prop(settings, "server_password", text="") row = layout.row() - row.prop(settings, "admin_password", text="Admin password") + col = row.column() + col.prop(settings, "use_admin_password", text="Admin password:") + col = row.column() + col.enabled = True if settings.use_admin_password else False + col.prop(settings, "admin_password", text="") def execute(self, context): assert(context) @@ -1037,6 +1063,8 @@ class SessionPresetServerEdit(bpy.types.Operator): server.server_server_password = settings.server_password server.server_admin_password = settings.admin_password + refresh_sidebar_view() + self.report({'INFO'}, "Server '" + settings.server_name + "' override") return {'FINISHED'} @@ -1064,6 +1092,37 @@ class SessionPresetServerRemove(bpy.types.Operator): return {'FINISHED'} +class GetDoc(bpy.types.Operator): + """Get the documentation of the addon""" + bl_idname = "doc.get" + bl_label = "Multi-user's doc" + bl_description = "Go to the doc of the addon" + + @classmethod + def poll(cls, context): + return True + + def execute(self, context): + assert(context) + bpy.ops.wm.url_open(url="https://multi-user.readthedocs.io/en/develop/index.html") + + return {'FINISHED'} + +class FirstLaunch(bpy.types.Operator): + """First time lauching the addon""" + bl_idname = "firstlaunch.verify" + bl_label = "First launch" + bl_description = "First time lauching the addon" + + @classmethod + def poll(cls, context): + return True + + def execute(self, context): + assert(context) + settings = utils.get_preferences() + settings.is_first_launch = False + return {'FINISHED'} def menu_func_import(self, context): self.layout.operator(SessionLoadSaveOperator.bl_idname, text='Multi-user session snapshot (.db)') @@ -1090,6 +1149,8 @@ classes = ( SessionPresetServerAdd, SessionPresetServerEdit, SessionPresetServerRemove, + GetDoc, + FirstLaunch, ) diff --git a/multi_user/preferences.py b/multi_user/preferences.py index 8177270..a6fbe4f 100644 --- a/multi_user/preferences.py +++ b/multi_user/preferences.py @@ -115,12 +115,14 @@ class ReplicatedDatablock(bpy.types.PropertyGroup): auto_push: bpy.props.BoolProperty(default=True) icon: bpy.props.StringProperty() -class ServerPreset(bpy.types.PropertyGroup): # TODO: self.uuid = uuid if uuid else str(uuid4()) - server_name: bpy.props.StringProperty() - server_ip: bpy.props.StringProperty() +class ServerPreset(bpy.types.PropertyGroup): + server_name: bpy.props.StringProperty(default="") + server_ip: bpy.props.StringProperty(default="127.0.0.1") server_port: bpy.props.IntProperty(default=5555) + use_server_password: bpy.props.BoolProperty(default=False) server_server_password: bpy.props.StringProperty(default="", subtype = "PASSWORD") - server_admin_password: bpy.props.StringProperty(default="admin", subtype = "PASSWORD") + use_admin_password: bpy.props.BoolProperty(default=False) + server_admin_password: bpy.props.StringProperty(default="", subtype = "PASSWORD") def set_sync_render_settings(self, value): self['sync_render_settings'] = value @@ -198,17 +200,31 @@ class SessionPrefs(bpy.types.AddonPreferences): name="server_index", description="index of the server", ) + use_server_password: bpy.props.BoolProperty( + name="use_server_password", + description='Use session password', + default=False + ) server_password: bpy.props.StringProperty( name="server_password", description='Session password', subtype='PASSWORD' ) + use_admin_password: bpy.props.BoolProperty( + name="use_admin_password", + description='Use admin password', + default=False + ) admin_password: bpy.props.StringProperty( name="admin_password", - default=random_string_digits(), description='Admin password', subtype='PASSWORD' ) + is_first_launch: bpy.props.BoolProperty( + name="is_first_launch", + description="First time lauching the addon", + default=True + ) sync_flags: bpy.props.PointerProperty( type=ReplicationFlags ) @@ -354,6 +370,11 @@ class SessionPrefs(bpy.types.AddonPreferences): description="sidebar_advanced_log_expanded", default=False ) + sidebar_advanced_hosting_expanded: bpy.props.BoolProperty( + name="sidebar_advanced_hosting_expanded", + description="sidebar_advanced_hosting_expanded", + default=False + ) sidebar_advanced_net_expanded: bpy.props.BoolProperty( name="sidebar_advanced_net_expanded", description="sidebar_advanced_net_expanded", @@ -431,10 +452,11 @@ class SessionPrefs(bpy.types.AddonPreferences): grid = layout.column() box = grid.box() - row = box.row(align = True) + row = box.row() # USER SETTINGS - row.prop(self, "username", text="User") - row.prop(self, "client_color", text="") + split = row.split(factor=0.7, align=True) + split.prop(self, "username", text="User") + split.prop(self, "client_color", text="") row = box.row() row.label(text="Hide settings:") @@ -457,9 +479,17 @@ class SessionPrefs(bpy.types.AddonPreferences): row.label(text="Init the session from:") row.prop(self, "init_method", text="") row = box.row() - row.prop(self, "server_password", text="Server password") + col = row.column() + col.prop(self, "use_server_password", text="Server password:") + col = row.column() + col.enabled = True if self.use_server_password else False + col.prop(self, "server_password", text="") row = box.row() - row.prop(self, "admin_password", text="Admin password") + col = row.column() + col.prop(self, "use_admin_password", text="Admin password:") + col = row.column() + col.enabled = True if self.use_admin_password else False + col.prop(self, "admin_password", text="") # NETWORKING box = grid.box() @@ -467,7 +497,6 @@ class SessionPrefs(bpy.types.AddonPreferences): self, "conf_session_net_expanded", text="Network", icon=get_expanded_icon(self.conf_session_net_expanded), emboss=False) - if self.conf_session_net_expanded: row = box.row() row.label(text="Timeout (ms):") @@ -479,16 +508,12 @@ class SessionPrefs(bpy.types.AddonPreferences): self, "conf_session_rep_expanded", text="Replication", icon=get_expanded_icon(self.conf_session_rep_expanded), emboss=False) - if self.conf_session_rep_expanded: - row = box.row() - row = box.row() row.prop(self.sync_flags, "sync_render_settings") row = box.row() row.prop(self.sync_flags, "sync_active_camera") row = box.row() - row.prop(self.sync_flags, "sync_during_editmode") row = box.row() if self.sync_flags.sync_during_editmode: @@ -519,8 +544,6 @@ class SessionPrefs(bpy.types.AddonPreferences): row.label(text="Log level:") row.prop(self, 'logging_level', text="") - - if self.category == 'UPDATE': from . import addon_updater_ops addon_updater_ops.update_settings_ui(self, context) @@ -540,11 +563,19 @@ class SessionPrefs(bpy.types.AddonPreferences): new_db.icon = impl.bl_icon new_db.bl_name = impl.bl_id + def get_server_preset(self, name): + existing_preset = None + + for server_preset in self.server_preset : + if server_preset.server_name == name : + existing_preset = server_preset + + return existing_preset # custom at launch server preset def generate_default_presets(self): for preset_name, preset_data in DEFAULT_PRESETS.items(): - existing_preset = self.server_preset.get(preset_name) + existing_preset = self.get_server_preset(preset_name) if existing_preset : continue new_server = self.server_preset.add() diff --git a/multi_user/temp.py b/multi_user/temp.py new file mode 100644 index 0000000..fd8c431 --- /dev/null +++ b/multi_user/temp.py @@ -0,0 +1,117 @@ +class SESSION_PT_network(bpy.types.Panel): + bl_idname = "MULTIUSER_SETTINGS_PT_network" + bl_label = "Network" + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_parent_id = 'MULTIUSER_SETTINGS_PT_network' + + @classmethod + def poll(cls, context): + return not session \ + or (session and session.state == 0) + + def draw_header(self, context): + self.layout.label(text="", icon='LINKED') + + def draw(self, context): + layout = self.layout + + runtime_settings = context.window_manager.session + settings = get_preferences() + + # Create a simple row. + row = layout.row() + box = row.box() + split = box.split(factor=0.35) + split.label(text="Server") + split = split.split(factor=0.3) + split.label(text="Online") + + row = layout.row() + layout.template_list("SESSION_UL_network", "", settings, + "server_preset_interface", context.window_manager, "user_index") + + +class SESSION_UL_network(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag): + settings = get_preferences() + server_name = '-' + server_status = 'BLANK1' + server_private = 'BLANK1' + + if not session: + server_name = settings.server_name + + # Session with/without password + if settings.server_password != None: + server_private = 'LOCKED' + split = layout.split(factor=0.35) + split.label(text=server_name, icon=server_private) + else: + split = layout.split(factor=0.35) + split.label(text=server_name) + + # Session status + # if session online : vert else rouge + from multi_user import icons + server_status = icons.icons_col["session_status_offline"] + split.label(icon=server_status) + +class SESSION_UL_users(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag): + settings = get_preferences() + is_local_user = item.username == settings.username + ping = '-' + frame_current = '-' + scene_current = '-' + mode_current = '-' + mode_icon = 'BLANK1' + status_icon = 'BLANK1' + if session: + user = session.online_users.get(item.username) + if user: + ping = str(user['latency']) + metadata = user.get('metadata') + if metadata and 'frame_current' in metadata: + frame_current = str(metadata.get('frame_current','-')) + scene_current = metadata.get('scene_current','-') + mode_current = metadata.get('mode_current','-') + if mode_current == "OBJECT" : + mode_icon = "OBJECT_DATAMODE" + elif mode_current == "EDIT_MESH" : + mode_icon = "EDITMODE_HLT" + elif mode_current == 'EDIT_CURVE': + mode_icon = "CURVE_DATA" + elif mode_current == 'EDIT_SURFACE': + mode_icon = "SURFACE_DATA" + elif mode_current == 'EDIT_TEXT': + mode_icon = "FILE_FONT" + elif mode_current == 'EDIT_ARMATURE': + mode_icon = "ARMATURE_DATA" + elif mode_current == 'EDIT_METABALL': + mode_icon = "META_BALL" + elif mode_current == 'EDIT_LATTICE': + mode_icon = "LATTICE_DATA" + elif mode_current == 'POSE': + mode_icon = "POSE_HLT" + elif mode_current == 'SCULPT': + mode_icon = "SCULPTMODE_HLT" + elif mode_current == 'PAINT_WEIGHT': + mode_icon = "WPAINT_HLT" + elif mode_current == 'PAINT_VERTEX': + mode_icon = "VPAINT_HLT" + elif mode_current == 'PAINT_TEXTURE': + mode_icon = "TPAINT_HLT" + elif mode_current == 'PARTICLE': + mode_icon = "PARTICLES" + elif mode_current == 'PAINT_GPENCIL' or mode_current =='EDIT_GPENCIL' or mode_current =='SCULPT_GPENCIL' or mode_current =='WEIGHT_GPENCIL' or mode_current =='VERTEX_GPENCIL': + mode_icon = "GREASEPENCIL" + if user['admin']: + status_icon = 'FAKE_USER_ON' + split = layout.split(factor=0.35) + split.label(text=item.username, icon=status_icon) + split = split.split(factor=0.3) + split.label(icon=mode_icon) + split.label(text=frame_current) + split.label(text=scene_current) + split.label(text=ping) \ No newline at end of file diff --git a/multi_user/ui.py b/multi_user/ui.py index f96f2be..2aca267 100644 --- a/multi_user/ui.py +++ b/multi_user/ui.py @@ -97,79 +97,103 @@ class SESSION_PT_settings(bpy.types.Panel): def draw(self, context): layout = self.layout - row = layout.row() runtime_settings = context.window_manager.session settings = get_preferences() - if hasattr(context.window_manager, 'session'): - # STATE INITIAL - if not session \ - or (session and session.state == STATE_INITIAL): - layout = self.layout - settings = get_preferences() - server_preset = settings.server_preset - selected_server = context.window_manager.server_index if context.window_manager.server_index<=len(server_preset)-1 else 0 - active_server_name = server_preset[selected_server].name if len(server_preset)>=1 else "" - is_server_selected = True if active_server_name else False # TODO : issues when removing the lowest server in the list + if settings.is_first_launch: + # USER SETTINGS + row = layout.row() + row.label(text="1. Enter your username and color:") + row = layout.row() + split = row.split(factor=0.7, align=True) + split.prop(settings, "username", text="") + split.prop(settings, "client_color", text="") - # Create a simple row. - row = layout.row() - box = row.box() - split = box.split(factor=0.7) - split.label(text="Server") - split.label(text="Online") + # DOC + row = layout.row() + row.label(text="2. New here ? See the doc:") + row = layout.row() + row.operator("doc.get", text="Documentation", icon="HELP") + + # START + row = layout.row() + row.label(text="3: Start the Multi-user:") + row = layout.row() + row.scale_y = 2 + row.operator("firstlaunch.verify", text="Continue") + + if not settings.is_first_launch: + if hasattr(context.window_manager, 'session'): + # STATE INITIAL + if not session \ + or (session and session.state == STATE_INITIAL): + layout = self.layout + settings = get_preferences() + server_preset = settings.server_preset + selected_server = context.window_manager.server_index if context.window_manager.server_index<=len(server_preset)-1 else 0 + active_server_name = server_preset[selected_server].name if len(server_preset)>=1 else "" + is_server_selected = True if active_server_name else False # TODO : issues when removing the lowest server in the list - row = layout.row() - layout.template_list("SESSION_UL_network", "", settings, "server_preset", context.window_manager, "server_index") # TODO: change port to server_index + # SERVER LIST + row = layout.row() + box = row.box() + split = box.split(factor=0.7) + split.label(text="Server") + split.label(text="Online") - row = layout.row() # TODO : active server in template - row.operator("session.preset_server_add", text="Add") # TODO : add conditions (need a name, etc..) + add a checkbox for password without creating preferences - col = row.column() - col.enabled = is_server_selected - col.operator("session.preset_server_edit", text="Edit").target_server_name = active_server_name - col = row.column() - col.enabled = is_server_selected - col.operator("session.preset_server_remove", text="Remove").target_server_name = active_server_name + row = layout.row() + layout.template_list("SESSION_UL_network", "", settings, "server_preset", context.window_manager, "server_index") - row = layout.row() - row.operator("session.host", text="Host") # TODO : add a pop-up for admin and server password ? - col = row.column() - col.enabled =is_server_selected - col.operator("session.connect", text="Connect") - else: - progress = session.state_progress - row = layout.row() + row = layout.row() # TODO : active server in template + row.operator("session.preset_server_add", text="Add") # TODO : add conditions (need a name, etc..) + add a checkbox for password without creating preferences + col = row.column() + col.enabled = is_server_selected + col.operator("session.preset_server_edit", text="Edit").target_server_name = active_server_name + col = row.column() + col.enabled = is_server_selected + col.operator("session.preset_server_remove", text="Remove").target_server_name = active_server_name - current_state = session.state - info_msg = None + row = layout.row() + row.operator("session.host", text="Host") # TODO : add a pop-up for admin and server password ? + col = row.column() + col.enabled =is_server_selected + col.operator("session.connect", text="Connect") - if current_state in [STATE_ACTIVE]: - row = row.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - row.prop(settings.sync_flags, "sync_render_settings",text="",icon_only=True, icon='SCENE') - row.prop(settings.sync_flags, "sync_during_editmode", text="",icon_only=True, icon='EDITMODE_HLT') - row.prop(settings.sync_flags, "sync_active_camera", text="",icon_only=True, icon='VIEW_CAMERA') + else: + progress = session.state_progress + row = layout.row() - row= layout.row() + current_state = session.state + info_msg = None - if current_state in [STATE_ACTIVE] and runtime_settings.is_host: - info_msg = f"LAN: {runtime_settings.internet_ip}" - if current_state == STATE_LOBBY: - info_msg = "Waiting for the session to start." + # STATE IN SESSION + if current_state in [STATE_ACTIVE]: + row = row.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) + row.prop(settings.sync_flags, "sync_render_settings",text="",icon_only=True, icon='SCENE') + row.prop(settings.sync_flags, "sync_during_editmode", text="",icon_only=True, icon='EDITMODE_HLT') + row.prop(settings.sync_flags, "sync_active_camera", text="",icon_only=True, icon='VIEW_CAMERA') - if info_msg: - info_box = row.box() - info_box.row().label(text=info_msg,icon='INFO') + row= layout.row() - # Progress bar - if current_state in [STATE_SYNCING, STATE_SRV_SYNC, STATE_WAITING]: - info_box = row.box() - info_box.row().label(text=printProgressBar( - progress['current'], - progress['total'], - length=16 - )) + if current_state in [STATE_ACTIVE] and runtime_settings.is_host: + info_msg = f"LAN: {runtime_settings.internet_ip}" + if current_state == STATE_LOBBY: + info_msg = "Waiting for the session to start." - layout.row().operator("session.stop", icon='QUIT', text="Exit") + if info_msg: + info_box = row.box() + info_box.row().label(text=info_msg,icon='INFO') + + # PROGRESS BAR + if current_state in [STATE_SYNCING, STATE_SRV_SYNC, STATE_WAITING]: + info_box = row.box() + info_box.row().label(text=printProgressBar( + progress['current'], + progress['total'], + length=16 + )) + + layout.row().operator("session.stop", icon='QUIT', text="Exit") class SESSION_PT_advanced_settings(bpy.types.Panel): bl_idname = "MULTIUSER_SETTINGS_REPLICATION_PT_panel" @@ -184,17 +208,40 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): settings = get_preferences() return not session \ or (session and session.state == 0) \ - and not settings.sidebar_advanced_shown + and not settings.sidebar_advanced_shown \ + and not settings.is_first_launch def draw_header(self, context): self.layout.label(text="", icon='PREFERENCES') def draw(self, context): layout = self.layout - - runtime_settings = context.window_manager.session settings = get_preferences() + #ADVANCED HOST + host_selection = layout.row().box() + host_selection.prop( + settings, "sidebar_advanced_hosting_expanded", text="Hosting", + icon=get_expanded_icon(settings.sidebar_advanced_hosting_expanded), + emboss=False) + if settings.sidebar_advanced_hosting_expanded: + host_selection_row = host_selection.row() + host_selection_row.label(text="Init the session from:") + host_selection_row.prop(settings, "init_method", text="") + host_selection_row = host_selection.row() + host_selection_col = host_selection_row.column() + host_selection_col.prop(settings, "use_server_password", text="Server password:") + host_selection_col = host_selection_row.column() + host_selection_col.enabled = True if settings.use_server_password else False + host_selection_col.prop(settings, "server_password", text="") + host_selection_row = host_selection.row() + host_selection_col = host_selection_row.column() + host_selection_col.prop(settings, "use_admin_password", text="Admin password:") + host_selection_col = host_selection_row.column() + host_selection_col.enabled = True if settings.use_admin_password else False + host_selection_col.prop(settings, "admin_password", text="") + + #ADVANCED NET net_section = layout.row().box() net_section.prop( settings, @@ -202,12 +249,12 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): text="Network", icon=get_expanded_icon(settings.sidebar_advanced_net_expanded), emboss=False) - if settings.sidebar_advanced_net_expanded: net_section_row = net_section.row() net_section_row.label(text="Timeout (ms):") net_section_row.prop(settings, "connection_timeout", text="") + #ADVANCED REPLICATION replication_section = layout.row().box() replication_section.prop( settings, @@ -215,16 +262,12 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): text="Replication", icon=get_expanded_icon(settings.sidebar_advanced_rep_expanded), emboss=False) - if settings.sidebar_advanced_rep_expanded: - replication_section_row = replication_section.row() - replication_section_row = replication_section.row() replication_section_row.prop(settings.sync_flags, "sync_render_settings") replication_section_row = replication_section.row() replication_section_row.prop(settings.sync_flags, "sync_active_camera") replication_section_row = replication_section.row() - replication_section_row.prop(settings.sync_flags, "sync_during_editmode") replication_section_row = replication_section.row() if settings.sync_flags.sync_during_editmode: @@ -233,7 +276,7 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): replication_section_row = replication_section.row() replication_section_row.prop(settings, "depsgraph_update_rate", text="Apply delay") - + #ADVANCED CACHE cache_section = layout.row().box() cache_section.prop( settings, @@ -251,6 +294,8 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): cache_section_row.prop(settings, "clear_memory_filecache", text="") cache_section_row = cache_section.row() cache_section_row.operator('session.clear_cache', text=f"Clear cache ({get_folder_size(settings.cache_directory)})") + + #ADVANCED LOG log_section = layout.row().box() log_section.prop( settings, @@ -258,7 +303,6 @@ class SESSION_PT_advanced_settings(bpy.types.Panel): text="Logging", icon=get_expanded_icon(settings.sidebar_advanced_log_expanded), emboss=False) - if settings.sidebar_advanced_log_expanded: log_section_row = log_section.row() log_section_row.label(text="Log level:") @@ -273,7 +317,8 @@ class SESSION_PT_user(bpy.types.Panel): @classmethod def poll(cls, context): - return session and session.state in [STATE_ACTIVE, STATE_LOBBY] + return session \ + and session.state in [STATE_ACTIVE, STATE_LOBBY] def draw_header(self, context): self.layout.label(text="", icon='USER') @@ -285,9 +330,8 @@ class SESSION_PT_user(bpy.types.Panel): settings = get_preferences() active_user = online_users[selected_user] if len( online_users)-1 >= selected_user else 0 - runtime_settings = context.window_manager.session - # Create a simple row. + #USER LIST row = layout.row() box = row.box() split = box.split(factor=0.35) @@ -302,6 +346,7 @@ class SESSION_PT_user(bpy.types.Panel): layout.template_list("SESSION_UL_users", "", context.window_manager, "online_users", context.window_manager, "user_index") + #OPERATOR ON USER if active_user != 0 and active_user.username != settings.username: row = layout.row() user_operations = row.split() @@ -387,7 +432,6 @@ class SESSION_UL_users(bpy.types.UIList): def draw_property(context, parent, property_uuid, level=0): settings = get_preferences() - runtime_settings = context.window_manager.session item = session.repository.graph.get(property_uuid) type_id = item.data.get('type_id') area_msg = parent.row(align=True) @@ -561,7 +605,7 @@ class VIEW3D_PT_overlay_session(bpy.types.Panel): text_scale.active = settings.presence_show_session_status text_scale.prop(pref, "presence_hud_scale", expand=True) - + class SESSION_UL_network(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag): settings = get_preferences() @@ -584,7 +628,7 @@ class SESSION_UL_network(bpy.types.UIList): # TODO : if session online : vert else rouge # TODO : ping from multi_user import icons - server_status = icons.icons_col["session_status_offline"] + server_status = icons.icons_col["server_offline"] split.label(icon_value=server_status.icon_id) classes = (