First Commit
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from . import (ui_list, panels)
|
||||
|
||||
modules = (
|
||||
ui_list,
|
||||
panels
|
||||
)
|
||||
|
||||
# if 'bpy' in locals():
|
||||
# import importlib
|
||||
# for mod in modules:
|
||||
# importlib.reload(mod)
|
||||
|
||||
import bpy
|
||||
|
||||
def register():
|
||||
for mod in modules:
|
||||
mod.register()
|
||||
|
||||
def unregister():
|
||||
for mod in reversed(modules):
|
||||
mod.unregister()
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
import bpy
|
||||
from bpy.types import Panel
|
||||
from .. constants import BGCOL, PREFIX
|
||||
|
||||
class BPM_PT_bg_manager_panel(Panel):
|
||||
bl_idname = 'BPM_PT_bg_manager_panel'
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_category = "View"
|
||||
bl_label = "BG Plane Manager"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scn = bpy.context.scene
|
||||
|
||||
# layout.label(text='Manual tests:')
|
||||
# layout.operator('bpm.import_bg_images')
|
||||
# layout.operator('bpm.convert_planes')
|
||||
|
||||
## Camera swapping
|
||||
row = layout.row(align=True)
|
||||
cam = context.scene.camera
|
||||
|
||||
# cam_name = cam.name if cam else 'None'
|
||||
# if cam and cam_name == 'draw_cam':
|
||||
# cam_name = f'{cam.parent.name} > {cam_name}'
|
||||
# row.operator("bpm.swap_cams", text=cam_name, icon='OUTLINER_OB_CAMERA')
|
||||
|
||||
if cam:
|
||||
anim_cam_name = 'anim_cam'
|
||||
bg_cam_name = 'bg_cam'
|
||||
in_anim = in_bg = False
|
||||
|
||||
if cam.name == 'anim_cam':
|
||||
in_anim = True
|
||||
|
||||
elif cam.name == 'bg_cam':
|
||||
in_bg = True
|
||||
|
||||
elif cam.name == 'draw_cam' and cam.parent:
|
||||
if cam.parent.name == 'anim_cam':
|
||||
in_anim = True
|
||||
anim_cam_name = anim_cam_name + '> draw_cam'
|
||||
|
||||
elif cam.parent.name == 'bg_cam':
|
||||
in_bg = True
|
||||
bg_cam_name = bg_cam_name + '> draw_cam'
|
||||
|
||||
# in_bg_cam = context.scene.camera.name != 'bg_cam'
|
||||
row.operator("bpm.swap_cams", text=anim_cam_name, icon='OUTLINER_OB_CAMERA', depress=in_anim)
|
||||
row.operator("bpm.swap_cams", text=bg_cam_name, icon='OUTLINER_OB_CAMERA', depress=in_bg)
|
||||
|
||||
planes = [i.plane for i in scn.bg_props.planes]
|
||||
|
||||
if not planes:
|
||||
## Show import/reload if nothing is in list
|
||||
row = layout.row()
|
||||
row.operator("bpm.import_bg_images", icon="IMPORT", text="Import Planes")
|
||||
row.operator("bpm.reload_list", icon="FILE_REFRESH", text="")
|
||||
return
|
||||
|
||||
## Show settings related to active plane
|
||||
active_item = scn.bg_props.planes[scn.bg_props.index]
|
||||
ob = active_item.plane
|
||||
if not ob:
|
||||
layout.operator("bpm.reload_list", icon="FILE_REFRESH", text="Need refresh")
|
||||
return
|
||||
|
||||
bg_main_col = context.view_layer.layer_collection.children.get(BGCOL)
|
||||
if not bg_main_col:
|
||||
layout.label(text="No Background collection")
|
||||
layout.label(text="Import plane automatically create hierarchy")
|
||||
return
|
||||
|
||||
if active_item.type == 'bg':
|
||||
layercol = bg_main_col.children.get(ob.name[len(PREFIX):])
|
||||
if not layercol:
|
||||
layout.label(text=f"No {ob.name} collection")
|
||||
# return
|
||||
|
||||
col= layout.column()
|
||||
## Backgrounds and Objects UI List
|
||||
col.separator()
|
||||
row = col.row()
|
||||
list_row = row.row()
|
||||
list_row.scale_y = scn.bg_props.ui_list_scale # 1.6
|
||||
minimum_rows = 8
|
||||
list_row.template_list("BPM_UL_bg_list", "", scn.bg_props, "planes", scn.bg_props, "index", rows=minimum_rows)
|
||||
#https://docs.blender.org/api/blender2.8/bpy.types.UILayout.html#bpy.types.UILayout.template_list
|
||||
|
||||
col = row.column(align=True)
|
||||
|
||||
col.operator('bpm.create_and_place_in_camera', icon='OUTLINER_OB_GREASEPENCIL', text='').create = True
|
||||
|
||||
col.separator()
|
||||
|
||||
col.menu("BPM_MT_more_option", icon='DOWNARROW_HLT', text='')
|
||||
|
||||
col.separator()
|
||||
|
||||
col.operator('bpm.move_plane', icon='TRIA_UP', text='').direction = 'UP'
|
||||
col.operator('bpm.move_plane', icon='TRIA_DOWN', text='').direction = 'DOWN'
|
||||
|
||||
col.separator()
|
||||
# select toggle
|
||||
# icon = 'RESTRICT_SELECT_ON' if ob.select_get() else 'RESTRICT_SELECT_OFF'
|
||||
# col.operator("bpm.select_swap_active_bg", icon=icon, text='')
|
||||
|
||||
# lock
|
||||
bg_col = bpy.data.collections.get(BGCOL)
|
||||
if bg_col:
|
||||
# lock_icon = 'LOCKED' if bg_col.hide_select else 'UNLOCKED'
|
||||
col.prop(bg_col, 'hide_select', icon='LOCKED', text='', invert_checkbox=True) # # emboss=False
|
||||
# col.prop(bg_col, 'hide_select', text='') # origin select icon
|
||||
|
||||
# select all
|
||||
col.operator('bpm.select_all', icon='RESTRICT_SELECT_OFF', text='')
|
||||
|
||||
col = layout.column()
|
||||
col.use_property_split = True
|
||||
if active_item.type == 'bg':
|
||||
row = col.row()
|
||||
tex_ob = next((o for o in ob.children), None)
|
||||
if not tex_ob:
|
||||
layout.label(text='Missing Image Child', icon='ERROR')
|
||||
return
|
||||
|
||||
row.prop(scn.bg_props, 'opacity', slider=True)
|
||||
|
||||
# row.operator("bpm.change_background_type", icon="NODE_TEXTURE", text=text_bg_type)
|
||||
|
||||
if tex_ob.type == 'MESH' and len(tex_ob.data.materials):
|
||||
text_mode = 'Clip' if tex_ob.data.materials[0].blend_method == 'CLIP' else 'Blend'
|
||||
row.operator("bpm.change_material_alpha_mode", icon="MATERIAL", text=text_mode)
|
||||
|
||||
# located under list
|
||||
row = layout.row()
|
||||
row.label(text='Move:')
|
||||
if active_item.type == 'bg':
|
||||
row.operator("bpm.set_distance", text=f"Distance {ob['distance']:.1f}m")
|
||||
row.prop(scn.bg_props, 'move_hided', text='Hided')
|
||||
|
||||
elif active_item.type == 'obj':
|
||||
cam = context.scene.objects.get('bg_cam') or context.scene.camera
|
||||
if hasattr(bpy.types, 'OBJECT_OT_depth_proportional_move'):
|
||||
distance = (ob.matrix_world.to_translation() - cam.matrix_world.to_translation()).length
|
||||
row.operator("object.depth_proportional_move", text=f"Distance {distance:.1f}m") # icon='TRANSFORM_ORIGINS'
|
||||
else:
|
||||
row.label(text=f"Distance {(ob.matrix_world.to_translation() - cam.matrix_world.to_translation()).length:.1f}m")
|
||||
|
||||
if active_item.type == 'bg':
|
||||
row = layout.row()
|
||||
# row.label(text='Actions:')
|
||||
## Send object to a plane
|
||||
row = layout.row()
|
||||
row.operator("bpm.send_gp_to_plane")
|
||||
## parent to object
|
||||
active = context.object
|
||||
if active and active.parent and active not in planes:
|
||||
layout.label(text=f'{active.parent.name} > {active.name}')
|
||||
text='Clear Parent '
|
||||
else:
|
||||
text='Parent To Plane'
|
||||
row.operator("bpm.parent_to_bg", text=text)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(BPM_PT_bg_manager_panel)
|
||||
|
||||
def unregister():
|
||||
if hasattr(bpy.types, BPM_PT_bg_manager_panel.bl_idname):
|
||||
bpy.utils.unregister_class(BPM_PT_bg_manager_panel)
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
import bpy
|
||||
from pathlib import Path
|
||||
from .. import fn
|
||||
from .. constants import PREFIX
|
||||
from bpy.types import UIList, PropertyGroup, Menu
|
||||
from bpy.props import (PointerProperty,
|
||||
IntProperty,
|
||||
BoolProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
FloatProperty
|
||||
)
|
||||
|
||||
class BPM_UL_bg_list(UIList):
|
||||
# order_by_distance : BoolProperty(default=True)
|
||||
|
||||
show_items : EnumProperty(
|
||||
name="Show Items", description="Filter items to show, GP objects, Background or all",
|
||||
default='all', options={'HIDDEN'},
|
||||
items=(
|
||||
('all', 'All', 'Show Background and Gp object', '', 0),
|
||||
('obj', 'Gp Objects', 'Show only Gp object', '', 1),
|
||||
('bg', 'Backgrounds', 'Show only backgrounds', '', 2),
|
||||
))
|
||||
#(key, label, descr, id[, icon])
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
|
||||
# layout.alignment = 'CENTER'
|
||||
|
||||
## TODO: Find a better solution to get the collection
|
||||
## Get Collection from plane name -> problem: prefix "BG_" and suffix
|
||||
# if not item.plane.get('is_background_holder'):
|
||||
if not item.plane.name.startswith(PREFIX): # (can check if has a parent using PREFIX)
|
||||
gp_ob = item.plane
|
||||
layout.prop(gp_ob, 'hide_viewport', text='', emboss=False, icon='HIDE_OFF')
|
||||
|
||||
icon_col = layout.row()
|
||||
icon_col.label(text='', icon='OUTLINER_OB_GREASEPENCIL') # BLANK1
|
||||
icon_col.ui_units_x = context.scene.bg_props.ui_list_scale # 1.6
|
||||
|
||||
row = layout.row()
|
||||
row.label(text=gp_ob.name)
|
||||
|
||||
if gp_ob.data.users > 1:
|
||||
row.template_ID(item, "data")
|
||||
else:
|
||||
row.label(text='', icon='BLANK1')
|
||||
|
||||
row.label(text='', icon='BLANK1')# <- add selection
|
||||
|
||||
return
|
||||
|
||||
layercol = context.view_layer.layer_collection.children['Background'].children.get(fn.clean_image_name(item.plane.name[len(PREFIX):]))
|
||||
if not layercol:
|
||||
layout.label(text=f'{item.plane.name} (problem with name)', icon='ERROR')
|
||||
return
|
||||
|
||||
# icon = 'HIDE_ON' if layercol.exclude else 'HIDE_OFF'
|
||||
layout.prop(layercol, 'exclude', text='', emboss=False, icon='HIDE_OFF')
|
||||
|
||||
if not item.plane.children:
|
||||
layout.label(text=f'{item.plane.name} (No children)', icon='ERROR')
|
||||
|
||||
## Image preview
|
||||
image = fn.get_image(item.plane.children[0])
|
||||
# layout.label(icon_value=image.preview_ensure().icon_id)
|
||||
# layout.template_icon(icon_value=image.preview_ensure().icon_id)
|
||||
|
||||
icon_col = layout.row()
|
||||
icon_col.template_icon(icon_value=image.preview_ensure().icon_id, scale=1.0)
|
||||
icon_col.ui_units_x = context.scene.bg_props.ui_list_scale # 1.6
|
||||
|
||||
## Name
|
||||
row = layout.row()
|
||||
row.enabled = not layercol.exclude
|
||||
|
||||
# row.label(text=item.plane.name) # <- Object has BG_ prefix, trim or use collection name
|
||||
row.label(text=layercol.name)
|
||||
|
||||
if context.scene.bg_props.show_distance:# and not layercol.exclude:
|
||||
row = layout.row()
|
||||
# row.enabled = not layercol.exclude
|
||||
row.prop(item.plane, '["distance"]', text='')
|
||||
# layout.prop(item.plane, 'location', index=2, text='') # , emboss=False
|
||||
|
||||
ob = context.object
|
||||
if ob and ob.parent == item.plane:
|
||||
layout.label(text='', icon='DECORATE_LINKED') # select from prop group
|
||||
else:
|
||||
layout.label(text='', icon='BLANK1') # select from prop group
|
||||
|
||||
if not layercol.exclude:
|
||||
icon = 'LAYER_ACTIVE' if item.plane.select_get() else 'LAYER_USED'
|
||||
layout.prop(item, 'select', icon=icon, text='', emboss=False) # select from prop group
|
||||
else:
|
||||
layout.label(text='', icon='BLANK1') # select from prop group
|
||||
|
||||
|
||||
|
||||
## note
|
||||
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
|
||||
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
|
||||
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
|
||||
# Note "data" names should never be translated!
|
||||
|
||||
def draw_filter(self, context, layout):
|
||||
row = layout.row()
|
||||
|
||||
subrow = row.row(align=True)
|
||||
subrow.prop(self, "filter_name", text="") # Only show items matching this name (use ‘*’ as wildcard)
|
||||
|
||||
# invert result
|
||||
# icon = 'ZOOM_OUT' if self.use_filter_invert else 'ZOOM_IN'
|
||||
# subrow.prop(self, "use_filter_invert", text="", icon=icon)
|
||||
|
||||
# sort by name : ALPHA SORTING NOT WORKING, MUST CHANGE IN filter_items
|
||||
# subrow.prop(self, "use_filter_sort_alpha", text="", icon='SORTALPHA') # buit-in sort
|
||||
|
||||
subrow.prop(self, "show_items", text="") # type enum filter # icon='DOWNARROW_HLT'
|
||||
|
||||
# reverse order
|
||||
icon = 'SORT_DESC' if self.use_filter_sort_reverse else 'SORT_ASC'
|
||||
subrow.prop(self, "use_filter_sort_reverse", text="", icon=icon) # built-in reverse
|
||||
|
||||
def filter_items(self, context, data, propname):
|
||||
helpers = bpy.types.UI_UL_list
|
||||
items = getattr(data, propname)
|
||||
|
||||
filtered = []
|
||||
|
||||
# ordered = [items[:].index(i) for i in sorted(items[:], key=lambda o: o.plane.location.z)]
|
||||
items = [(items[:].index(i), i) for i in items[:]]
|
||||
|
||||
# needed ?
|
||||
filtered = [self.bitflag_filter_item] * len(items)
|
||||
|
||||
## Filter out out items thata
|
||||
for i, item in items:
|
||||
## GP/BG Type filter
|
||||
if self.show_items != 'all':
|
||||
if self.show_items != item.type:
|
||||
filtered[i] &= ~self.bitflag_filter_item
|
||||
## Search filter
|
||||
if item.plane and self.filter_name.lower() not in item.plane.name.lower():
|
||||
filtered[i] &= ~self.bitflag_filter_item
|
||||
|
||||
|
||||
# if self.order_by_distance:
|
||||
cam = context.scene.objects.get('bg_cam') or context.scene.camera
|
||||
if not cam:
|
||||
return filtered, ordered
|
||||
|
||||
## Real Distance from bg_cam or active camera
|
||||
ordered = helpers.sort_items_helper(items, lambda o: (o[1].plane.matrix_world.to_translation() - cam.matrix_world.to_translation()).length)
|
||||
## By distance attribute (only Backgrounds have distance attr)
|
||||
# ordered = helpers.sort_items_helper(items, lambda o: o[1].plane.get('distance'))
|
||||
|
||||
return filtered, ordered
|
||||
|
||||
'''
|
||||
class BPM_UL_bg_list(UIList):
|
||||
# order_by_distance : BoolProperty(default=True)
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
|
||||
# layout.alignment = 'CENTER'
|
||||
|
||||
## TODO: Find a better solution to get the collection
|
||||
## Get Collection from plane name -> problem: prefix "BG_" and suffix
|
||||
|
||||
layercol = context.view_layer.layer_collection.children['Background'].children.get(fn.clean_image_name(item.plane.name[len(PREFIX):]))
|
||||
if not layercol:
|
||||
layout.label(text=f'{item.plane.name} (problem with name)', icon='ERROR')
|
||||
return
|
||||
|
||||
# icon = 'HIDE_ON' if layercol.exclude else 'HIDE_OFF'
|
||||
layout.prop(layercol, 'exclude', text='', emboss=False, icon='HIDE_OFF')
|
||||
|
||||
if not item.plane.children:
|
||||
layout.label(text=f'{item.plane.name} (No children)', icon='ERROR')
|
||||
|
||||
## Image preview
|
||||
image = fn.get_image(item.plane.children[0])
|
||||
# layout.label(icon_value=image.preview_ensure().icon_id)
|
||||
# layout.template_icon(icon_value=image.preview_ensure().icon_id)
|
||||
|
||||
icon_col = layout.row()
|
||||
icon_col.template_icon(icon_value=image.preview_ensure().icon_id, scale=1.0)
|
||||
icon_col.ui_units_x = context.scene.bg_props.ui_list_scale # 1.6
|
||||
|
||||
|
||||
## Name
|
||||
row = layout.row()
|
||||
row.enabled = not layercol.exclude
|
||||
|
||||
# row.label(text=item.plane.name) # <- Object has BG_ prefix, trim or use collection name
|
||||
row.label(text=layercol.name)
|
||||
|
||||
ob = context.object
|
||||
if ob and ob.parent == item.plane:
|
||||
layout.label(text='', icon='DECORATE_LINKED') # select from prop group
|
||||
else:
|
||||
layout.label(text='', icon='BLANK1') # select from prop group
|
||||
|
||||
if not layercol.exclude:
|
||||
icon = 'LAYER_ACTIVE' if item.plane.select_get() else 'LAYER_USED'
|
||||
layout.prop(item, 'select', icon=icon, text='', emboss=False) # select from prop group
|
||||
else:
|
||||
layout.label(text='', icon='BLANK1') # select from prop group
|
||||
|
||||
if context.scene.bg_props.show_distance:# and not layercol.exclude:
|
||||
row = layout.row()
|
||||
# row.enabled = not layercol.exclude
|
||||
row.prop(item.plane, '["distance"]', text='')
|
||||
# layout.prop(item.plane, 'location', index=2, text='') # , emboss=False
|
||||
|
||||
|
||||
## note
|
||||
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
|
||||
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
|
||||
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
|
||||
# Note "data" names should never be translated!
|
||||
|
||||
|
||||
def filter_items(self, context, data, propname):
|
||||
helpers = bpy.types.UI_UL_list
|
||||
items = getattr(data, propname)
|
||||
|
||||
filtered = []
|
||||
|
||||
# ordered = [items[:].index(i) for i in sorted(items[:], key=lambda o: o.plane.location.z)]
|
||||
items = [(items[:].index(i), i) for i in items[:]]
|
||||
|
||||
# needed ?
|
||||
filtered = [self.bitflag_filter_item] * len(items)
|
||||
|
||||
for i, item in items:
|
||||
if item.plane and self.filter_name.lower() not in item.plane.name.lower():
|
||||
filtered[i] &= ~self.bitflag_filter_item
|
||||
#else:
|
||||
|
||||
|
||||
# if self.order_by_distance:
|
||||
|
||||
ordered = helpers.sort_items_helper(items, lambda o: o[1].plane.get('distance'))
|
||||
|
||||
return filtered, ordered
|
||||
|
||||
# def draw_filter(self, context, layout):
|
||||
# """UI code for the filtering/sorting/search area."""
|
||||
# col = layout.column(align=True)
|
||||
# row = col.row(align=True)
|
||||
|
||||
# # row.prop(self, 'order_by_distance', text='', icon='DRIVER_DISTANCE')
|
||||
# # row.prop(self, 'use_filter_invert', text='', icon='ARROW_LEFTRIGHT')
|
||||
'''
|
||||
|
||||
### --- updates
|
||||
|
||||
def get_plane_targets(context):
|
||||
selection = [i.plane for i in context.scene.bg_props.planes if i.plane.select_get()]
|
||||
if selection:
|
||||
return selection
|
||||
## active (even not selected)
|
||||
return [context.scene.bg_props.planes[context.scene.bg_props.index].plane]
|
||||
|
||||
def update_opacity(self, context):
|
||||
pool = get_plane_targets(context)
|
||||
for ob in pool:
|
||||
if not ob or not ob.children:
|
||||
continue
|
||||
fn.set_opacity(ob.children[0], opacity=context.scene.bg_props.opacity)
|
||||
|
||||
def update_on_index_change(self, context):
|
||||
# print('index change:', context.scene.bg_props.index)
|
||||
props = context.scene.bg_props
|
||||
planes_list = props.planes
|
||||
item = planes_list[props.index]
|
||||
if not item.plane:
|
||||
## remove slot !
|
||||
print(f'bg_props.planes: No plane/object at index {props.index}, removing item')
|
||||
planes_list.remove(props.index)
|
||||
return
|
||||
|
||||
if item.type == 'bg':
|
||||
plane = item.plane
|
||||
if not plane.children:
|
||||
return
|
||||
opacity = fn.get_opacity(plane.children[0])
|
||||
if not opacity:
|
||||
return
|
||||
props['opacity'] = opacity
|
||||
|
||||
elif item.type == 'obj':
|
||||
fn.gp_transfer_mode(item.plane, context)
|
||||
|
||||
|
||||
def update_select(self, context):
|
||||
# print('index change:', context.scene.bg_props.index)
|
||||
plane = self.plane
|
||||
plane.select_set(not plane.select_get())
|
||||
context.scene.bg_props['index'] = context.scene.bg_props.planes[:].index(self)
|
||||
|
||||
class BPM_more_option(Menu):
|
||||
bl_idname = "BPM_MT_more_option"
|
||||
bl_label = "Options"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.operator("bpm.reload_list", text="Refresh", icon="FILE_REFRESH")
|
||||
layout.operator("bpm.open_bg_folder", icon="FILE_FOLDER")
|
||||
layout.operator("bpm.import_bg_images", text="Import Planes", icon="IMPORT")
|
||||
layout.operator("bpm.convert_planes", text="Convert Planes", icon="OUTLINER_OB_IMAGE")
|
||||
layout.separator()
|
||||
layout.prop(context.scene.bg_props, 'show_distance', icon='DRIVER_DISTANCE')
|
||||
layout.prop(context.scene.bg_props, 'ui_list_scale')
|
||||
|
||||
# Create sniptool property group
|
||||
class BPM_bg_list_prop(PropertyGroup):
|
||||
plane : PointerProperty(type=bpy.types.Object)
|
||||
select: BoolProperty(update=update_select) # use and update to set the plane selection
|
||||
type: StringProperty(default='bg')
|
||||
# is_bg: BoolProperty(default=True)
|
||||
|
||||
|
||||
class BPM_bg_settings(PropertyGroup):
|
||||
index : IntProperty(update=update_on_index_change)
|
||||
planes : bpy.props.CollectionProperty(type=BPM_bg_list_prop)
|
||||
show_distance : BoolProperty(name='Show Distance', default=False)
|
||||
opacity : FloatProperty(name='Opacity', default=1.0, min=0.0, max=1.0, update=update_opacity)
|
||||
move_hided : BoolProperty(name='Move hided', default=True)
|
||||
ui_list_scale : FloatProperty(name='UI Item Y Scale', default=1.6, min=0.6, soft_min=1.0, max=2.0)
|
||||
# distance : FloatProperty(name='Distance', default=0.0, update=update_distance)
|
||||
|
||||
|
||||
### --- REGISTER ---
|
||||
|
||||
classes=(
|
||||
# prop and UIlist
|
||||
BPM_bg_list_prop,
|
||||
BPM_bg_settings,
|
||||
BPM_UL_bg_list,
|
||||
BPM_more_option,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
bpy.types.Scene.bg_props = bpy.props.PointerProperty(type=BPM_bg_settings)
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
del bpy.types.Scene.bg_props
|
||||
Reference in New Issue
Block a user