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:
parent
44e525aec7
commit
8b7716ac3c
@ -177,6 +177,12 @@ class SessionProps(bpy.types.PropertyGroup):
|
||||
description='Show only owned datablocks',
|
||||
default=True
|
||||
)
|
||||
user_snap_running: bpy.props.BoolProperty(
|
||||
default=False
|
||||
)
|
||||
time_snap_running: bpy.props.BoolProperty(
|
||||
default=False
|
||||
)
|
||||
|
||||
def load(self):
|
||||
config = environment.load_config()
|
||||
|
@ -237,6 +237,7 @@ class ClientUpdate(Timer):
|
||||
settings.client_color.g,
|
||||
settings.client_color.b,
|
||||
1),
|
||||
'frame_current':bpy.context.scene.frame_current
|
||||
}
|
||||
session.update_user_metadata(metadata)
|
||||
elif current_view_corners != local_user_metadata['view_corners']:
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit aff1bd53c5ca4e1f43a0ba6bf86c34e51b5721db
|
||||
Subproject commit aeb290f3b54a1cd14a74c569a2f0116bdbb46684
|
@ -36,6 +36,7 @@ modal_executor_queue = None
|
||||
|
||||
# OPERATORS
|
||||
|
||||
|
||||
class SessionStartOperator(bpy.types.Operator):
|
||||
bl_idname = "session.start"
|
||||
bl_label = "start"
|
||||
@ -51,7 +52,7 @@ class SessionStartOperator(bpy.types.Operator):
|
||||
global client, delayables, ui_context
|
||||
settings = context.window_manager.session
|
||||
users = bpy.data.window_managers['WinMan'].online_users
|
||||
|
||||
|
||||
# TODO: Sync server clients
|
||||
users.clear()
|
||||
|
||||
@ -67,7 +68,7 @@ class SessionStartOperator(bpy.types.Operator):
|
||||
type_module = getattr(bl_types, type)
|
||||
type_impl_name = "Bl{}".format(type.split('_')[1].capitalize())
|
||||
type_module_class = getattr(type_module, type_impl_name)
|
||||
|
||||
|
||||
supported_bl_types.append(type_module_class.bl_id)
|
||||
|
||||
# Retreive local replicated types settings
|
||||
@ -85,8 +86,6 @@ class SessionStartOperator(bpy.types.Operator):
|
||||
target_type=type_module_class))
|
||||
|
||||
client = Session(factory=bpy_factory)
|
||||
|
||||
|
||||
|
||||
if self.host:
|
||||
# Scene setup
|
||||
@ -124,7 +123,7 @@ class SessionStartOperator(bpy.types.Operator):
|
||||
|
||||
# for node in client.list():
|
||||
client.commit(scene_uuid)
|
||||
|
||||
|
||||
delayables.append(delayable.ClientUpdate())
|
||||
delayables.append(delayable.DrawClient())
|
||||
delayables.append(delayable.DynamicRightSelectTimer())
|
||||
@ -254,6 +253,14 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
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)
|
||||
wm.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
@ -263,7 +270,9 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
||||
wm.event_timer_remove(self._timer)
|
||||
|
||||
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)
|
||||
return {'CANCELLED'}
|
||||
|
||||
@ -283,6 +292,58 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
||||
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):
|
||||
bl_idname = "session.apply"
|
||||
bl_label = "apply selected block into blender"
|
||||
@ -372,25 +433,30 @@ classes = (
|
||||
SessionStopOperator,
|
||||
SessionPropertyRemoveOperator,
|
||||
SessionSnapUserOperator,
|
||||
SessionSnapTimeOperator,
|
||||
SessionPropertyRightOperator,
|
||||
SessionApply,
|
||||
SessionCommit,
|
||||
ApplyArmatureOperator,
|
||||
|
||||
|
||||
)
|
||||
|
||||
|
||||
@persistent
|
||||
def load_pre_handler(dummy):
|
||||
global client
|
||||
|
||||
if client and client.state in [STATE_ACTIVE, STATE_SYNCING]:
|
||||
bpy.ops.session.stop()
|
||||
|
||||
|
||||
|
||||
@persistent
|
||||
def sanitize_deps_graph(dummy):
|
||||
"""sanitize deps graph
|
||||
|
||||
Temporary solution to resolve each node pointers after a Undo.
|
||||
A future solution should be to avoid storing dataclock reference...
|
||||
A future solution should be to avoid storing dataclock reference...
|
||||
|
||||
"""
|
||||
global client
|
||||
@ -399,6 +465,15 @@ def sanitize_deps_graph(dummy):
|
||||
for node_key in client.list():
|
||||
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():
|
||||
from bpy.utils import register_class
|
||||
for cls in classes:
|
||||
@ -409,6 +484,9 @@ def register():
|
||||
bpy.app.handlers.undo_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():
|
||||
global client
|
||||
|
||||
@ -419,11 +497,14 @@ def unregister():
|
||||
from bpy.utils import unregister_class
|
||||
for cls in reversed(classes):
|
||||
unregister_class(cls)
|
||||
|
||||
bpy.app.handlers.load_pre.remove(load_pre_handler)
|
||||
|
||||
bpy.app.handlers.load_pre.remove(load_pre_handler)
|
||||
|
||||
bpy.app.handlers.undo_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__":
|
||||
register()
|
||||
|
@ -198,10 +198,17 @@ class SESSION_PT_user(bpy.types.Panel):
|
||||
if active_user != 0 and active_user.username != settings.username:
|
||||
row = layout.row()
|
||||
user_operations = row.split()
|
||||
user_operations.alert = context.window_manager.session.time_snap_running
|
||||
user_operations.operator(
|
||||
"session.snapview",
|
||||
text="",
|
||||
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):
|
||||
@ -210,17 +217,18 @@ class SESSION_UL_users(bpy.types.UIList):
|
||||
settings = context.window_manager.session
|
||||
is_local_user = item.username == settings.username
|
||||
ping = '-'
|
||||
|
||||
frame_current = '-'
|
||||
if session:
|
||||
users = session.online_users
|
||||
for user, user_stat in users.items():
|
||||
if item.username in user:
|
||||
ping = str(user_stat['latency'])
|
||||
break
|
||||
user = session.online_users.get(item.username)
|
||||
if user:
|
||||
ping = str(user['latency'])
|
||||
metadata = user.get('metadata')
|
||||
if metadata:
|
||||
frame_current = str(metadata['frame_current'])
|
||||
|
||||
split = layout.split(factor=0.5)
|
||||
split.label(text=item.username)
|
||||
split.label(text=str(item.current_frame))
|
||||
split.label(text=frame_current)
|
||||
split.label(text=ping)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user