feat(rcf): improve UI
This commit is contained in:
parent
c8dfbcb87a
commit
11cb91fb8e
200
net_operators.py
200
net_operators.py
@ -1,3 +1,4 @@
|
||||
from bpy_extras import view3d_utils
|
||||
import bpy
|
||||
from . import net_components
|
||||
from . import net_ui
|
||||
@ -19,7 +20,7 @@ server = None
|
||||
context = None
|
||||
|
||||
|
||||
COLOR_TABLE = [(1,0,0,1),(0,1,0,1),(0,0,1,1)]
|
||||
COLOR_TABLE = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1)]
|
||||
NATIVE_TYPES = (
|
||||
bpy.types.IntProperty,
|
||||
bpy.types.FloatProperty,
|
||||
@ -27,10 +28,6 @@ NATIVE_TYPES = (
|
||||
bpy.types.StringProperty,
|
||||
)
|
||||
|
||||
import mathutils
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
from bpy_extras import view3d_utils
|
||||
|
||||
def view3d_find():
|
||||
for area in bpy.context.window.screen.areas:
|
||||
@ -40,68 +37,71 @@ def view3d_find():
|
||||
for region in area.regions:
|
||||
if region.type == 'WINDOW':
|
||||
return area, region, rv3d
|
||||
|
||||
|
||||
break
|
||||
|
||||
|
||||
return None, None, None
|
||||
|
||||
def get_target(region, rv3d,coord):
|
||||
|
||||
def get_target(region, rv3d, coord):
|
||||
view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
|
||||
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
|
||||
target = ray_origin +view_vector
|
||||
return [target.x,target.y,target.z]
|
||||
target = ray_origin + view_vector
|
||||
return [target.x, target.y, target.z]
|
||||
|
||||
|
||||
def get_client_view_rect():
|
||||
area, region, rv3d = view3d_find()
|
||||
|
||||
v1 = [0,0,0]
|
||||
v2 = [0,0,0]
|
||||
v3 = [0,0,0]
|
||||
v4 = [0,0,0]
|
||||
v1 = [0, 0, 0]
|
||||
v2 = [0, 0, 0]
|
||||
v3 = [0, 0, 0]
|
||||
v4 = [0, 0, 0]
|
||||
|
||||
|
||||
width = region.width
|
||||
height = region.height
|
||||
|
||||
v1 = get_target(region,rv3d,(0,0))
|
||||
v3 = get_target(region,rv3d,(0,height))
|
||||
v2 = get_target(region,rv3d,(width,height))
|
||||
v4 = get_target(region,rv3d,(width,0))
|
||||
v1 = get_target(region, rv3d, (0, 0))
|
||||
v3 = get_target(region, rv3d, (0, height))
|
||||
v2 = get_target(region, rv3d, (width, height))
|
||||
v4 = get_target(region, rv3d, (width, 0))
|
||||
|
||||
coords = (v1, v2, v3, v4)
|
||||
indices = (
|
||||
(1, 3), (2, 1), (3, 0),(2,0)
|
||||
(1, 3), (2, 1), (3, 0), (2, 0)
|
||||
)
|
||||
return coords
|
||||
|
||||
|
||||
def get_client_view_rect():
|
||||
area, region, rv3d = view3d_find()
|
||||
|
||||
v1 = [0,0,0]
|
||||
v2 = [0,0,0]
|
||||
v3 = [0,0,0]
|
||||
v4 = [0,0,0]
|
||||
v1 = [0, 0, 0]
|
||||
v2 = [0, 0, 0]
|
||||
v3 = [0, 0, 0]
|
||||
v4 = [0, 0, 0]
|
||||
|
||||
|
||||
width = region.width
|
||||
height = region.height
|
||||
|
||||
v1 = get_target(region,rv3d,(0,0))
|
||||
v3 = get_target(region,rv3d,(0,height))
|
||||
v2 = get_target(region,rv3d,(width,height))
|
||||
v4 = get_target(region,rv3d,(width,0))
|
||||
v1 = get_target(region, rv3d, (0, 0))
|
||||
v3 = get_target(region, rv3d, (0, height))
|
||||
v2 = get_target(region, rv3d, (width, height))
|
||||
v4 = get_target(region, rv3d, (width, 0))
|
||||
|
||||
coords = (v1, v2, v3, v4)
|
||||
indices = (
|
||||
(1, 3), (2, 1), (3, 0),(2,0)
|
||||
(1, 3), (2, 1), (3, 0), (2, 0)
|
||||
)
|
||||
return coords
|
||||
|
||||
|
||||
def get_client_2d(coords):
|
||||
area, region, rv3d = view3d_find()
|
||||
|
||||
return view3d_utils.location_3d_to_region_2d(region,rv3d,coords)
|
||||
|
||||
return view3d_utils.location_3d_to_region_2d(region, rv3d, coords)
|
||||
|
||||
|
||||
class UpdateClientView(bpy.types.Operator):
|
||||
bl_idname = "session.update_client"
|
||||
bl_label = "update client"
|
||||
@ -118,15 +118,14 @@ class UpdateClientView(bpy.types.Operator):
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def invoke(self, context,event):
|
||||
self.coords = get_client_view_rect()
|
||||
def invoke(self, context, event):
|
||||
self.coords = get_client_view_rect()
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
self.register_handlers(context)
|
||||
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
|
||||
def modal(self, context, event):
|
||||
if context.area:
|
||||
context.area.tag_redraw()
|
||||
@ -134,33 +133,33 @@ class UpdateClientView(bpy.types.Operator):
|
||||
if event.type in {"TIMER"}:
|
||||
current_coords = get_client_view_rect()
|
||||
# Update local view
|
||||
if current_coords != self.coords:
|
||||
if current_coords != self.coords:
|
||||
global client
|
||||
|
||||
self.coords= current_coords
|
||||
self.coords = current_coords
|
||||
key = "net/clients/{}".format(client.id.decode())
|
||||
|
||||
|
||||
client.push_update(key, 'client', current_coords)
|
||||
print("update")
|
||||
|
||||
|
||||
if event.type in {"ESC"}:
|
||||
self.unregister_handlers(context)
|
||||
return {"CANCELLED"}
|
||||
|
||||
self.unregister_handlers(context)
|
||||
return {"CANCELLED"}
|
||||
|
||||
return {"PASS_THROUGH"}
|
||||
|
||||
def register_handlers(self,context):
|
||||
self.update_event = context.window_manager.event_timer_add(0.1, window=context.window)
|
||||
def register_handlers(self, context):
|
||||
self.update_event = context.window_manager.event_timer_add(
|
||||
0.1, window=context.window)
|
||||
|
||||
def unregister_handlers(self,context):
|
||||
def unregister_handlers(self, context):
|
||||
context.window_manager.event_timer_remove(self.draw_event)
|
||||
|
||||
|
||||
def finish(self):
|
||||
self.unregister_handlers()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
def on_scene_evalutation(scene):
|
||||
# TODO: viewer representation
|
||||
# TODO: Live update only selected object
|
||||
@ -268,9 +267,11 @@ def refresh_window():
|
||||
|
||||
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
||||
|
||||
|
||||
def init_scene(msg):
|
||||
pass
|
||||
|
||||
|
||||
def update_scene(msg):
|
||||
global client
|
||||
|
||||
@ -294,13 +295,15 @@ def update_scene(msg):
|
||||
else:
|
||||
logger.debug('no need to update scene on our own')
|
||||
|
||||
|
||||
def update_ui(msg):
|
||||
"""
|
||||
Update collaborative UI elements
|
||||
"""
|
||||
pass
|
||||
|
||||
recv_callbacks = [update_scene,update_ui]
|
||||
|
||||
recv_callbacks = [update_scene, update_ui]
|
||||
post_init_callbacks = [refresh_window]
|
||||
|
||||
|
||||
@ -328,8 +331,8 @@ class session_join(bpy.types.Operator):
|
||||
client_factory = rna_translation.RNAFactory()
|
||||
print("{}".format(client_factory.__class__.__name__))
|
||||
client = net_components.Client(
|
||||
id=username,
|
||||
on_recv=recv_callbacks,
|
||||
id=username,
|
||||
on_recv=recv_callbacks,
|
||||
on_post_init=post_init_callbacks,
|
||||
factory=client_factory)
|
||||
# time.sleep(1)
|
||||
@ -432,7 +435,7 @@ class session_stop(bpy.types.Operator):
|
||||
net_settings = context.scene.session_settings
|
||||
|
||||
bpy.app.timers.unregister(observer)
|
||||
|
||||
|
||||
if server:
|
||||
server.stop()
|
||||
del server
|
||||
@ -446,7 +449,6 @@ class session_stop(bpy.types.Operator):
|
||||
else:
|
||||
logger.debug("No server/client running.")
|
||||
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@ -457,50 +459,59 @@ class session_settings(bpy.types.PropertyGroup):
|
||||
port = bpy.props.IntProperty(name="5555")
|
||||
buffer = bpy.props.StringProperty(name="None")
|
||||
is_running = bpy.props.BoolProperty(name="is_running", default=False)
|
||||
hide_users = bpy.props.BoolProperty(name="is_running", default=False)
|
||||
hide_settings = bpy.props.BoolProperty(name="hide_settings", default=False)
|
||||
hide_properties = bpy.props.BoolProperty(name="hide_properties", default=True)
|
||||
update_frequency = bpy.props.FloatProperty(
|
||||
name="update_frequency", default=0.008)
|
||||
|
||||
|
||||
|
||||
class session_draw_clients(bpy.types.Operator):
|
||||
bl_idname = "session.draw"
|
||||
bl_label = "draw clients"
|
||||
bl_description = "Description that shows in blender tooltips"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
position = bpy.props.FloatVectorProperty(default=(0,0,0))
|
||||
position = bpy.props.FloatVectorProperty(default=(0, 0, 0))
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.draw_items = []
|
||||
self.draw_items = []
|
||||
self.draw3d_handle = None
|
||||
self.draw2d_handle = None
|
||||
self.draw_event = None
|
||||
self.coords = None
|
||||
|
||||
self.draw_event = None
|
||||
self.coords = None
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def invoke(self, context,event):
|
||||
#
|
||||
self.coords = get_client_view_rect()
|
||||
def invoke(self, context, event):
|
||||
#
|
||||
self.coords = get_client_view_rect()
|
||||
self.create_batch()
|
||||
self.register_handlers(context)
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def register_handlers(self,context):
|
||||
self.draw3d_handle = bpy.types.SpaceView3D.draw_handler_add(self.draw3d_callback, (), 'WINDOW', 'POST_VIEW')
|
||||
self.draw2d_handle = bpy.types.SpaceView3D.draw_handler_add(self.draw2d_callback, (), 'WINDOW', 'POST_PIXEL')
|
||||
def register_handlers(self, context):
|
||||
self.draw3d_handle = bpy.types.SpaceView3D.draw_handler_add(
|
||||
self.draw3d_callback, (), 'WINDOW', 'POST_VIEW')
|
||||
self.draw2d_handle = bpy.types.SpaceView3D.draw_handler_add(
|
||||
self.draw2d_callback, (), 'WINDOW', 'POST_PIXEL')
|
||||
|
||||
self.draw_event = context.window_manager.event_timer_add(0.1, window=context.window)
|
||||
self.draw_event = context.window_manager.event_timer_add(
|
||||
0.1, window=context.window)
|
||||
|
||||
def unregister_handlers(self,context):
|
||||
if self.draw_event and self.draw3d_handle:
|
||||
context.window_manager.event_timer_remove(self.draw_event)
|
||||
bpy.types.SpaceView3D.draw_handler_remove(self.draw3d_handle,"WINDOW")
|
||||
bpy.types.SpaceView3D.draw_handler_remove(self.draw2d_handle,"WINDOW")
|
||||
def unregister_handlers(self, context):
|
||||
if self.draw_event and self.draw3d_handle and self.draw2d_handle:
|
||||
context.window_manager.event_timer_remove(self.draw_event)
|
||||
bpy.types.SpaceView3D.draw_handler_remove(
|
||||
self.draw3d_handle, "WINDOW")
|
||||
bpy.types.SpaceView3D.draw_handler_remove(
|
||||
self.draw2d_handle, "WINDOW")
|
||||
|
||||
self.draw_items.clear()
|
||||
self.draw3d_handle = None
|
||||
@ -511,48 +522,47 @@ class session_draw_clients(bpy.types.Operator):
|
||||
global client
|
||||
index = 0
|
||||
for key, values in client.property_map.items():
|
||||
|
||||
if values.mtype == "client" and values.id != client.id:
|
||||
|
||||
indices = (
|
||||
(1, 3), (2, 1), (3, 0),(2,0)
|
||||
)
|
||||
|
||||
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": values.body}, indices=indices)
|
||||
if values.mtype == "client" and values.id != client.id:
|
||||
|
||||
indices = (
|
||||
(1, 3), (2, 1), (3, 0), (2, 0)
|
||||
)
|
||||
|
||||
self.draw_items.append((shader,batch, (values.body[1],values.id.decode()),COLOR_TABLE[index]))
|
||||
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
|
||||
batch = batch_for_shader(
|
||||
shader, 'LINES', {"pos": values.body}, indices=indices)
|
||||
|
||||
index+=1
|
||||
self.draw_items.append(
|
||||
(shader, batch, (values.body[1], values.id.decode()), COLOR_TABLE[index]))
|
||||
|
||||
index += 1
|
||||
|
||||
def draw3d_callback(self):
|
||||
|
||||
|
||||
bgl.glLineWidth(3)
|
||||
for shader,batch,font,color in self.draw_items:
|
||||
for shader, batch, font, color in self.draw_items:
|
||||
shader.bind()
|
||||
shader.uniform_float("color", color)
|
||||
batch.draw(shader)
|
||||
|
||||
|
||||
|
||||
def draw2d_callback(self):
|
||||
for shader,batch,font,color in self.draw_items:
|
||||
coords = get_client_2d(font[0])
|
||||
|
||||
for shader, batch, font, color in self.draw_items:
|
||||
coords = get_client_2d(font[0])
|
||||
|
||||
try:
|
||||
blf.position(0, coords[0], coords[1]+10, 0)
|
||||
blf.size(0, 10, 72)
|
||||
blf.color(0,color[0],color[1],color[2],color[3])
|
||||
blf.color(0, color[0], color[1], color[2], color[3])
|
||||
blf.draw(0, font[1])
|
||||
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
def modal(self, context, event):
|
||||
if context.area:
|
||||
context.area.tag_redraw()
|
||||
|
||||
|
||||
if not context.scene.session_settings.is_running:
|
||||
self.finish(context)
|
||||
|
||||
@ -561,22 +571,22 @@ class session_draw_clients(bpy.types.Operator):
|
||||
if client:
|
||||
# Local view update
|
||||
current_coords = get_client_view_rect()
|
||||
if current_coords != self.coords:
|
||||
self.coords= current_coords
|
||||
if current_coords != self.coords:
|
||||
self.coords = current_coords
|
||||
key = "net/clients/{}".format(client.id.decode())
|
||||
|
||||
|
||||
client.push_update(key, 'client', current_coords)
|
||||
|
||||
|
||||
# Draw clients
|
||||
if len(client.property_map) > 0:
|
||||
self.unregister_handlers(context)
|
||||
self.create_batch()
|
||||
|
||||
|
||||
self.register_handlers(context)
|
||||
|
||||
|
||||
return {"PASS_THROUGH"}
|
||||
|
||||
def finish(self,context):
|
||||
def finish(self, context):
|
||||
self.unregister_handlers(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
120
net_ui.py
120
net_ui.py
@ -3,21 +3,22 @@ from . import net_components
|
||||
from . import net_operators
|
||||
|
||||
|
||||
class SessionPanel(bpy.types.Panel):
|
||||
class SessionSettingsPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the scene context of the properties editor"""
|
||||
bl_label = "bl network"
|
||||
bl_idname = "SCENE_PT_layout"
|
||||
bl_label = "NET settings"
|
||||
bl_idname = "SCENE_PT_SessionSettings"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
|
||||
def draw_header(self, context):
|
||||
net_settings = context.scene.session_settings
|
||||
pass
|
||||
# net_settings = context.scene.session_settings
|
||||
|
||||
if net_settings.is_running:
|
||||
self.layout.label(text="",icon='HIDE_OFF')
|
||||
else:
|
||||
self.layout.label(text="",icon='HIDE_ON')
|
||||
# if net_settings.is_running:
|
||||
# self.layout.label(text="",icon='HIDE_OFF')
|
||||
# else:
|
||||
# self.layout.label(text="",icon='HIDE_ON')
|
||||
# self.layout.label(text="Offline")
|
||||
|
||||
def draw(self, context):
|
||||
@ -31,26 +32,11 @@ class SessionPanel(bpy.types.Panel):
|
||||
if net_operators.client:
|
||||
row.label(text="Net frequency:")
|
||||
row.prop(net_settings,"update_frequency",text="")
|
||||
row = layout.row(align=True)
|
||||
row.prop(net_settings,"buffer", text="")
|
||||
row.operator("session.add_prop", text="",icon="ADD").property_path = net_settings.buffer
|
||||
row = layout.row()
|
||||
# Debug area
|
||||
|
||||
|
||||
row = layout.row()
|
||||
area_msg = row.box()
|
||||
if len(net_operators.client.property_map) > 0:
|
||||
for key,values in net_operators.client.property_map.items():
|
||||
item_box = area_msg.box()
|
||||
detail_item_box = item_box.row()
|
||||
# detail_item_box = item_box.row()
|
||||
detail_item_box.label(text="{} ({}) ".format(key, values.mtype, values.id.decode()))
|
||||
detail_item_box.operator("session.remove_prop",text="",icon="X").property_path = key
|
||||
else:
|
||||
area_msg.label(text="Empty")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("session.stop")
|
||||
row.operator("session.stop", text="exit session")
|
||||
|
||||
else:
|
||||
row = layout.row()
|
||||
@ -61,10 +47,88 @@ class SessionPanel(bpy.types.Panel):
|
||||
row.operator("session.create")
|
||||
|
||||
row = layout.row()
|
||||
# row.operator("session.draw")
|
||||
# row.operator("session.update_client")
|
||||
|
||||
class SessionUsersPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the scene context of the properties editor"""
|
||||
bl_label = "NET users"
|
||||
bl_idname = "SCENE_PT_SessionUsers"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return net_operators.client
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
net_settings = context.scene.session_settings
|
||||
scene = context.scene
|
||||
# Create a simple row.
|
||||
row = layout.row()
|
||||
|
||||
if net_operators.client:
|
||||
if len(net_operators.client.property_map) > 0:
|
||||
for key,values in net_operators.client.property_map.items():
|
||||
if 'client' in key:
|
||||
info = ""
|
||||
item_box = row.box()
|
||||
detail_item_box = item_box.row()
|
||||
|
||||
if values.id == net_operators.client.id:
|
||||
info = "(self)"
|
||||
# detail_item_box = item_box.row()
|
||||
detail_item_box.label(text="{} {}".format(values.id.decode(),info))
|
||||
row = layout.row()
|
||||
else:
|
||||
row.label(text="Empty")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
|
||||
|
||||
class SessionPropertiesPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the scene context of the properties editor"""
|
||||
bl_label = "NET properties"
|
||||
bl_idname = "SCENE_PT_layout"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return net_operators.client
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
net_settings = context.scene.session_settings
|
||||
scene = context.scene
|
||||
# Create a simple row.
|
||||
row = layout.row()
|
||||
|
||||
if net_operators.client:
|
||||
row = layout.row(align=True)
|
||||
row.prop(net_settings,"buffer", text="")
|
||||
row.operator("session.add_prop", text="",icon="ADD").property_path = net_settings.buffer
|
||||
row = layout.row()
|
||||
# Property area
|
||||
area_msg = row.box()
|
||||
if len(net_operators.client.property_map) > 0:
|
||||
for key,values in net_operators.client.property_map.items():
|
||||
item_box = area_msg.box()
|
||||
detail_item_box = item_box.row()
|
||||
# detail_item_box = item_box.row()
|
||||
detail_item_box.label(text="{} ({}) ".format(key, values.mtype, values.id.decode()))
|
||||
detail_item_box.operator("session.remove_prop",text="",icon="X").property_path = key
|
||||
else:
|
||||
area_msg.label(text="Empty")
|
||||
|
||||
classes = (
|
||||
SessionPanel,
|
||||
SessionSettingsPanel,
|
||||
SessionUsersPanel,
|
||||
SessionPropertiesPanel,
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user