feat: snap time operator
feat: snap operators status It's now possible to snap to others user time's ! Related to #53.
This commit is contained in:
@ -177,6 +177,12 @@ class SessionProps(bpy.types.PropertyGroup):
|
|||||||
description='Show only owned datablocks',
|
description='Show only owned datablocks',
|
||||||
default=True
|
default=True
|
||||||
)
|
)
|
||||||
|
user_snap_running: bpy.props.BoolProperty(
|
||||||
|
default=False
|
||||||
|
)
|
||||||
|
time_snap_running: bpy.props.BoolProperty(
|
||||||
|
default=False
|
||||||
|
)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
config = environment.load_config()
|
config = environment.load_config()
|
||||||
|
@ -237,6 +237,7 @@ class ClientUpdate(Timer):
|
|||||||
settings.client_color.g,
|
settings.client_color.g,
|
||||||
settings.client_color.b,
|
settings.client_color.b,
|
||||||
1),
|
1),
|
||||||
|
'frame_current':bpy.context.scene.frame_current
|
||||||
}
|
}
|
||||||
session.update_user_metadata(metadata)
|
session.update_user_metadata(metadata)
|
||||||
elif current_view_corners != local_user_metadata['view_corners']:
|
elif current_view_corners != local_user_metadata['view_corners']:
|
||||||
|
Submodule multi_user/libs/replication updated: aff1bd53c5...aeb290f3b5
@ -36,6 +36,7 @@ modal_executor_queue = None
|
|||||||
|
|
||||||
# OPERATORS
|
# OPERATORS
|
||||||
|
|
||||||
|
|
||||||
class SessionStartOperator(bpy.types.Operator):
|
class SessionStartOperator(bpy.types.Operator):
|
||||||
bl_idname = "session.start"
|
bl_idname = "session.start"
|
||||||
bl_label = "start"
|
bl_label = "start"
|
||||||
@ -86,8 +87,6 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
client = Session(factory=bpy_factory)
|
client = Session(factory=bpy_factory)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if self.host:
|
if self.host:
|
||||||
# Scene setup
|
# Scene setup
|
||||||
if settings.start_empty:
|
if settings.start_empty:
|
||||||
@ -254,6 +253,14 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
|
settings = context.window_manager.session
|
||||||
|
|
||||||
|
if settings.time_snap_running:
|
||||||
|
settings.time_snap_running = False
|
||||||
|
return {'CANCELLED'}
|
||||||
|
else:
|
||||||
|
settings.time_snap_running = True
|
||||||
|
|
||||||
self._timer = wm.event_timer_add(0.1, window=context.window)
|
self._timer = wm.event_timer_add(0.1, window=context.window)
|
||||||
wm.modal_handler_add(self)
|
wm.modal_handler_add(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
@ -263,7 +270,9 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
|||||||
wm.event_timer_remove(self._timer)
|
wm.event_timer_remove(self._timer)
|
||||||
|
|
||||||
def modal(self, context, event):
|
def modal(self, context, event):
|
||||||
if event.type in {'RIGHTMOUSE', 'ESC'}:
|
is_running = context.window_manager.session.time_snap_running
|
||||||
|
|
||||||
|
if event.type in {'RIGHTMOUSE', 'ESC'} or not is_running:
|
||||||
self.cancel(context)
|
self.cancel(context)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
@ -283,6 +292,58 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
|||||||
return {'PASS_THROUGH'}
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
|
|
||||||
|
class SessionSnapTimeOperator(bpy.types.Operator):
|
||||||
|
bl_idname = "session.snaptime"
|
||||||
|
bl_label = "snap to user time"
|
||||||
|
bl_description = "Snap time to selected user time's"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
_timer = None
|
||||||
|
|
||||||
|
target_client: bpy.props.StringProperty(default="None")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
settings = context.window_manager.session
|
||||||
|
|
||||||
|
if settings.user_snap_running:
|
||||||
|
settings.user_snap_running = False
|
||||||
|
return {'CANCELLED'}
|
||||||
|
else:
|
||||||
|
settings.user_snap_running = True
|
||||||
|
|
||||||
|
wm = context.window_manager
|
||||||
|
self._timer = wm.event_timer_add(0.1, window=context.window)
|
||||||
|
wm.modal_handler_add(self)
|
||||||
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
def cancel(self, context):
|
||||||
|
wm = context.window_manager
|
||||||
|
wm.event_timer_remove(self._timer)
|
||||||
|
|
||||||
|
def modal(self, context, event):
|
||||||
|
is_running = context.window_manager.session.user_snap_running
|
||||||
|
if event.type in {'RIGHTMOUSE', 'ESC'} or not is_running:
|
||||||
|
self.cancel(context)
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
if event.type == 'TIMER':
|
||||||
|
global client
|
||||||
|
|
||||||
|
if client:
|
||||||
|
target_ref = client.online_users.get(self.target_client)
|
||||||
|
|
||||||
|
if target_ref:
|
||||||
|
context.scene.frame_current = target_ref['metadata']['frame_current']
|
||||||
|
else:
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
|
|
||||||
class SessionApply(bpy.types.Operator):
|
class SessionApply(bpy.types.Operator):
|
||||||
bl_idname = "session.apply"
|
bl_idname = "session.apply"
|
||||||
bl_label = "apply selected block into blender"
|
bl_label = "apply selected block into blender"
|
||||||
@ -372,12 +433,16 @@ classes = (
|
|||||||
SessionStopOperator,
|
SessionStopOperator,
|
||||||
SessionPropertyRemoveOperator,
|
SessionPropertyRemoveOperator,
|
||||||
SessionSnapUserOperator,
|
SessionSnapUserOperator,
|
||||||
|
SessionSnapTimeOperator,
|
||||||
SessionPropertyRightOperator,
|
SessionPropertyRightOperator,
|
||||||
SessionApply,
|
SessionApply,
|
||||||
SessionCommit,
|
SessionCommit,
|
||||||
ApplyArmatureOperator,
|
ApplyArmatureOperator,
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def load_pre_handler(dummy):
|
def load_pre_handler(dummy):
|
||||||
global client
|
global client
|
||||||
@ -385,6 +450,7 @@ def load_pre_handler(dummy):
|
|||||||
if client and client.state in [STATE_ACTIVE, STATE_SYNCING]:
|
if client and client.state in [STATE_ACTIVE, STATE_SYNCING]:
|
||||||
bpy.ops.session.stop()
|
bpy.ops.session.stop()
|
||||||
|
|
||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def sanitize_deps_graph(dummy):
|
def sanitize_deps_graph(dummy):
|
||||||
"""sanitize deps graph
|
"""sanitize deps graph
|
||||||
@ -399,6 +465,15 @@ def sanitize_deps_graph(dummy):
|
|||||||
for node_key in client.list():
|
for node_key in client.list():
|
||||||
client.get(node_key).resolve()
|
client.get(node_key).resolve()
|
||||||
|
|
||||||
|
|
||||||
|
@persistent
|
||||||
|
def update_client_frame(scene):
|
||||||
|
if client and client.state == STATE_ACTIVE:
|
||||||
|
client.update_user_metadata({
|
||||||
|
'frame_current': scene.frame_current
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
from bpy.utils import register_class
|
from bpy.utils import register_class
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
@ -409,6 +484,9 @@ def register():
|
|||||||
bpy.app.handlers.undo_post.append(sanitize_deps_graph)
|
bpy.app.handlers.undo_post.append(sanitize_deps_graph)
|
||||||
bpy.app.handlers.redo_post.append(sanitize_deps_graph)
|
bpy.app.handlers.redo_post.append(sanitize_deps_graph)
|
||||||
|
|
||||||
|
bpy.app.handlers.frame_change_pre.append(update_client_frame)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
global client
|
global client
|
||||||
|
|
||||||
@ -425,5 +503,8 @@ def unregister():
|
|||||||
bpy.app.handlers.undo_post.remove(sanitize_deps_graph)
|
bpy.app.handlers.undo_post.remove(sanitize_deps_graph)
|
||||||
bpy.app.handlers.redo_post.remove(sanitize_deps_graph)
|
bpy.app.handlers.redo_post.remove(sanitize_deps_graph)
|
||||||
|
|
||||||
|
bpy.app.handlers.frame_change_pre.remove(update_client_frame)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
register()
|
register()
|
||||||
|
@ -198,11 +198,18 @@ class SESSION_PT_user(bpy.types.Panel):
|
|||||||
if active_user != 0 and active_user.username != settings.username:
|
if active_user != 0 and active_user.username != settings.username:
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
user_operations = row.split()
|
user_operations = row.split()
|
||||||
|
user_operations.alert = context.window_manager.session.time_snap_running
|
||||||
user_operations.operator(
|
user_operations.operator(
|
||||||
"session.snapview",
|
"session.snapview",
|
||||||
text="",
|
text="",
|
||||||
icon='VIEW_CAMERA').target_client = active_user.username
|
icon='VIEW_CAMERA').target_client = active_user.username
|
||||||
|
|
||||||
|
user_operations.alert = context.window_manager.session.user_snap_running
|
||||||
|
user_operations.operator(
|
||||||
|
"session.snaptime",
|
||||||
|
text="",
|
||||||
|
icon='TIME').target_client = active_user.username
|
||||||
|
|
||||||
|
|
||||||
class SESSION_UL_users(bpy.types.UIList):
|
class SESSION_UL_users(bpy.types.UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag):
|
||||||
@ -210,17 +217,18 @@ class SESSION_UL_users(bpy.types.UIList):
|
|||||||
settings = context.window_manager.session
|
settings = context.window_manager.session
|
||||||
is_local_user = item.username == settings.username
|
is_local_user = item.username == settings.username
|
||||||
ping = '-'
|
ping = '-'
|
||||||
|
frame_current = '-'
|
||||||
if session:
|
if session:
|
||||||
users = session.online_users
|
user = session.online_users.get(item.username)
|
||||||
for user, user_stat in users.items():
|
if user:
|
||||||
if item.username in user:
|
ping = str(user['latency'])
|
||||||
ping = str(user_stat['latency'])
|
metadata = user.get('metadata')
|
||||||
break
|
if metadata:
|
||||||
|
frame_current = str(metadata['frame_current'])
|
||||||
|
|
||||||
split = layout.split(factor=0.5)
|
split = layout.split(factor=0.5)
|
||||||
split.label(text=item.username)
|
split.label(text=item.username)
|
||||||
split.label(text=str(item.current_frame))
|
split.label(text=frame_current)
|
||||||
split.label(text=ping)
|
split.label(text=ping)
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user