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:
Swann Martinez 2020-01-22 16:17:48 +01:00
parent 44e525aec7
commit 8b7716ac3c
No known key found for this signature in database
GPG Key ID: 414CCAFD8DA720E1
5 changed files with 114 additions and 18 deletions

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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)