Add Chromium-only Blender WebEngine parity work
This commit is contained in:
29
blender-5.2.0/scripts/templates_py/UI/asset_shelf.py
Normal file
29
blender-5.2.0/scripts/templates_py/UI/asset_shelf.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class MyAssetShelf(bpy.types.AssetShelf):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_idname = "VIEW3D_AST_my_asset_shelf"
|
||||
|
||||
# Tell the shelf which data-block types to show. It is highly recommended
|
||||
# to use these filters, as they avoid slowdowns when there are many assets
|
||||
# of irrelevant data-block types.
|
||||
# If no filter is set, all data-block types will show.
|
||||
filter_material = True
|
||||
filter_object = True
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.mode == 'OBJECT'
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(MyAssetShelf)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(MyAssetShelf)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
44
blender-5.2.0/scripts/templates_py/UI/list.py
Normal file
44
blender-5.2.0/scripts/templates_py/UI/list.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class MESH_UL_mylist(bpy.types.UIList):
|
||||
# Constants (flags)
|
||||
# Be careful not to shadow FILTER_ITEM (i.e. UIList().bitflag_filter_item)!
|
||||
# E.g. VGROUP_EMPTY = 1 << 0
|
||||
|
||||
# Custom properties, saved with .blend file. E.g.
|
||||
# use_filter_empty: bpy.props.BoolProperty(
|
||||
# name="Filter Empty", default=False, options=set(),
|
||||
# description="Whether to filter empty vertex groups",
|
||||
# )
|
||||
|
||||
# Called for each drawn item.
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag):
|
||||
pass
|
||||
|
||||
# Called once to draw filtering/reordering options.
|
||||
def draw_filter(self, context, layout):
|
||||
# Nothing much to say here, it's usual UI code...
|
||||
pass
|
||||
|
||||
# Called once to filter/reorder items.
|
||||
def filter_items(self, context, data, propname):
|
||||
# This function gets the collection property (as the usual tuple (data, propname)), and must return two lists:
|
||||
# * The first one is for filtering, it must contain 32bit integers were self.bitflag_filter_item marks the
|
||||
# matching item as filtered (i.e. to be shown). The upper 16 bits (including self.bitflag_filter_item) are
|
||||
# reserved for internal use, the lower 16 bits are free for custom use. Here we use the first bit to mark
|
||||
# VGROUP_EMPTY.
|
||||
# * The second one is for reordering, it must return a list containing the new indices of the items (which
|
||||
# gives us a mapping org_idx -> new_idx).
|
||||
# Please note that the default `UI_UL_list` defines helper functions for common tasks
|
||||
# (see its doc for more info).
|
||||
# If you do not make filtering and/or ordering, return empty list(s)
|
||||
# (this will be more efficient than returning full lists doing nothing!).
|
||||
|
||||
# Default return values.
|
||||
flt_flags = []
|
||||
flt_neworder = []
|
||||
|
||||
# Do filtering/reordering here...
|
||||
|
||||
return flt_flags, flt_neworder
|
||||
47
blender-5.2.0/scripts/templates_py/UI/list_generic.py
Normal file
47
blender-5.2.0/scripts/templates_py/UI/list_generic.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import bpy
|
||||
from bl_ui.generic_ui_list import draw_ui_list
|
||||
|
||||
|
||||
class MyPropGroup(bpy.types.PropertyGroup):
|
||||
name: bpy.props.StringProperty()
|
||||
|
||||
|
||||
class MyPanel(bpy.types.Panel):
|
||||
bl_label = "My Label"
|
||||
bl_idname = "SCENE_PT_list_demo"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "My Category"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
draw_ui_list(
|
||||
layout,
|
||||
context,
|
||||
list_path="scene.my_list",
|
||||
active_index_path="scene.my_list_active_index",
|
||||
unique_id="my_list_id",
|
||||
)
|
||||
|
||||
|
||||
classes = [
|
||||
MyPropGroup,
|
||||
MyPanel,
|
||||
]
|
||||
|
||||
class_register, class_unregister = bpy.utils.register_classes_factory(classes)
|
||||
|
||||
|
||||
def register():
|
||||
class_register()
|
||||
bpy.types.Scene.my_list = bpy.props.CollectionProperty(type=MyPropGroup)
|
||||
bpy.types.Scene.my_list_active_index = bpy.props.IntProperty()
|
||||
|
||||
|
||||
def unregister():
|
||||
class_unregister()
|
||||
del bpy.types.Scene.my_list
|
||||
del bpy.types.Scene.my_list_active_index
|
||||
|
||||
|
||||
register()
|
||||
70
blender-5.2.0/scripts/templates_py/UI/list_simple.py
Normal file
70
blender-5.2.0/scripts/templates_py/UI/list_simple.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class MATERIAL_UL_matslots_example(bpy.types.UIList):
|
||||
# The draw_item function is called for each item of the collection that is visible in the list.
|
||||
# data is the RNA object containing the collection,
|
||||
# item is the current drawn item of the collection,
|
||||
# icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
|
||||
# have custom icons ID, which are not available as enum items).
|
||||
# active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
|
||||
# active item of the collection).
|
||||
# active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
|
||||
# index is index of the current item in the collection.
|
||||
# flt_flag is the result of the filtering process for this item.
|
||||
# Note: as index and flt_flag are optional arguments, you do not have to use/declare them here if you don't
|
||||
# need them.
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
ob = data
|
||||
slot = item
|
||||
ma = slot.material
|
||||
# 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!
|
||||
if ma:
|
||||
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
|
||||
else:
|
||||
layout.label(text="", translate=False, icon_value=icon)
|
||||
|
||||
|
||||
# And now we can use this list everywhere in Blender. Here is a small example panel.
|
||||
class UIListPanelExample(bpy.types.Panel):
|
||||
"""Creates a Panel in the Object properties window"""
|
||||
bl_label = "UIList Panel"
|
||||
bl_idname = "OBJECT_PT_ui_list_example"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
obj = context.object
|
||||
|
||||
# `template_list` now takes two new arguments.
|
||||
# The first one is the identifier of the registered UIList to use (if you want only the default list,
|
||||
# with no custom draw code, use "UI_UL_list").
|
||||
layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index")
|
||||
|
||||
# The second one can usually be left as an empty string.
|
||||
# It's an additional ID used to distinguish lists in case you
|
||||
# use the same list several times in a given area.
|
||||
layout.template_list(
|
||||
"MATERIAL_UL_matslots_example", "compact", obj, "material_slots",
|
||||
obj, "active_material_index", type='COMPACT',
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(MATERIAL_UL_matslots_example)
|
||||
bpy.utils.register_class(UIListPanelExample)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(MATERIAL_UL_matslots_example)
|
||||
bpy.utils.unregister_class(UIListPanelExample)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
50
blender-5.2.0/scripts/templates_py/UI/menu.py
Normal file
50
blender-5.2.0/scripts/templates_py/UI/menu.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class CustomMenu(bpy.types.Menu):
|
||||
bl_label = "Custom Menu"
|
||||
bl_idname = "OBJECT_MT_custom_menu"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("wm.open_mainfile")
|
||||
layout.operator("wm.save_as_mainfile").copy = True
|
||||
|
||||
layout.operator("object.shade_smooth")
|
||||
|
||||
layout.label(text="Hello world!", icon='WORLD_DATA')
|
||||
|
||||
# use an operator enum property to populate a sub-menu
|
||||
layout.operator_menu_enum(
|
||||
"object.select_by_type",
|
||||
property="type",
|
||||
text="Select All by Type",
|
||||
)
|
||||
# call another menu
|
||||
layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
|
||||
|
||||
|
||||
def draw_item(self, context):
|
||||
layout = self.layout
|
||||
layout.menu(CustomMenu.bl_idname)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(CustomMenu)
|
||||
|
||||
# lets add ourselves to the main header
|
||||
bpy.types.INFO_HT_header.append(draw_item)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(CustomMenu)
|
||||
|
||||
bpy.types.INFO_HT_header.remove(draw_item)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# The menu can also be called from scripts
|
||||
bpy.ops.wm.call_menu(name=CustomMenu.bl_idname)
|
||||
27
blender-5.2.0/scripts/templates_py/UI/menu_simple.py
Normal file
27
blender-5.2.0/scripts/templates_py/UI/menu_simple.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class SimpleCustomMenu(bpy.types.Menu):
|
||||
bl_label = "Simple Custom Menu"
|
||||
bl_idname = "OBJECT_MT_simple_custom_menu"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("wm.open_mainfile")
|
||||
layout.operator("wm.save_as_mainfile")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(SimpleCustomMenu)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(SimpleCustomMenu)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# The menu can also be called from scripts
|
||||
bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)
|
||||
73
blender-5.2.0/scripts/templates_py/UI/panel.py
Normal file
73
blender-5.2.0/scripts/templates_py/UI/panel.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class LayoutDemoPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the scene context of the properties editor"""
|
||||
bl_label = "Layout Demo"
|
||||
bl_idname = "SCENE_PT_layout"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
# Create a simple row.
|
||||
layout.label(text=" Simple Row:")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(scene, "frame_start")
|
||||
row.prop(scene, "frame_end")
|
||||
|
||||
# Create an row where the buttons are aligned to each other.
|
||||
layout.label(text=" Aligned Row:")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene, "frame_start")
|
||||
row.prop(scene, "frame_end")
|
||||
|
||||
# Create two columns, by using a split layout.
|
||||
split = layout.split()
|
||||
|
||||
# First column
|
||||
col = split.column()
|
||||
col.label(text="Column One:")
|
||||
col.prop(scene, "frame_end")
|
||||
col.prop(scene, "frame_start")
|
||||
|
||||
# Second column, aligned
|
||||
col = split.column(align=True)
|
||||
col.label(text="Column Two:")
|
||||
col.prop(scene, "frame_start")
|
||||
col.prop(scene, "frame_end")
|
||||
|
||||
# Big render button
|
||||
layout.label(text="Big Button:")
|
||||
row = layout.row()
|
||||
row.scale_y = 3.0
|
||||
row.operator("render.render")
|
||||
|
||||
# Different sizes in a row
|
||||
layout.label(text="Different button sizes:")
|
||||
row = layout.row(align=True)
|
||||
row.operator("render.render")
|
||||
|
||||
sub = row.row()
|
||||
sub.scale_x = 2.0
|
||||
sub.operator("render.render")
|
||||
|
||||
row.operator("render.render")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(LayoutDemoPanel)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(LayoutDemoPanel)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
38
blender-5.2.0/scripts/templates_py/UI/panel_simple.py
Normal file
38
blender-5.2.0/scripts/templates_py/UI/panel_simple.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class HelloWorldPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the Object properties window"""
|
||||
bl_label = "Hello World Panel"
|
||||
bl_idname = "OBJECT_PT_hello"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
obj = context.object
|
||||
|
||||
row = layout.row()
|
||||
row.label(text="Hello world!", icon='WORLD_DATA')
|
||||
|
||||
row = layout.row()
|
||||
row.label(text="Active object is: " + obj.name)
|
||||
row = layout.row()
|
||||
row.prop(obj, "name")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("mesh.primitive_cube_add")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(HelloWorldPanel)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(HelloWorldPanel)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
31
blender-5.2.0/scripts/templates_py/UI/pie_menu.py
Normal file
31
blender-5.2.0/scripts/templates_py/UI/pie_menu.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
|
||||
# spawn an edit mode selection pie (run while object is in edit mode to get a valid output)
|
||||
|
||||
|
||||
class VIEW3D_MT_PIE_template(Menu):
|
||||
# label is displayed at the center of the pie menu.
|
||||
bl_label = "Select Mode"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
# operator_enum will just spread all available options
|
||||
# for the type enum of the operator on the pie
|
||||
pie.operator_enum("mesh.select_mode", "type")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(VIEW3D_MT_PIE_template)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(VIEW3D_MT_PIE_template)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
bpy.ops.wm.call_menu_pie(name="VIEW3D_MT_PIE_template")
|
||||
@@ -0,0 +1,76 @@
|
||||
# This sample script demonstrates how to place a custom icon on a button or
|
||||
# menu entry.
|
||||
#
|
||||
# IMPORTANT NOTE: if you run this sample, there will be no icon in the button
|
||||
# You need to replace the image path with a real existing one.
|
||||
# For distributable scripts, it is recommended to place the icons inside the
|
||||
# addon folder and access it relative to the py script file for portability
|
||||
#
|
||||
#
|
||||
# Other use cases for UI-previews:
|
||||
# - provide a fixed list of previews to select from
|
||||
# - provide a dynamic list of preview (eg. calculated from reading a directory)
|
||||
#
|
||||
# For the above use cases, see the template `ui_previews_dynamic_enum.py`.
|
||||
|
||||
|
||||
import os
|
||||
import bpy
|
||||
|
||||
|
||||
class PreviewsExamplePanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the Object properties window"""
|
||||
bl_label = "Previews Example Panel"
|
||||
bl_idname = "OBJECT_PT_previews"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
pcoll = preview_collections["main"]
|
||||
|
||||
row = layout.row()
|
||||
my_icon = pcoll["my_icon"]
|
||||
row.operator("render.render", icon_value=my_icon.icon_id)
|
||||
|
||||
# my_icon.icon_id can be used in any UI function that accepts
|
||||
# icon_value # try also setting text=""
|
||||
# to get an icon only operator button
|
||||
|
||||
|
||||
# We can store multiple preview collections here,
|
||||
# however in this example we only store "main"
|
||||
preview_collections = {}
|
||||
|
||||
|
||||
def register():
|
||||
|
||||
# Note that preview collections returned by bpy.utils.previews
|
||||
# are regular py objects - you can use them to store custom data.
|
||||
import bpy.utils.previews
|
||||
pcoll = bpy.utils.previews.new()
|
||||
|
||||
# path to the folder where the icon is
|
||||
# the path is calculated relative to this py file inside the addon folder
|
||||
my_icons_dir = os.path.join(os.path.dirname(__file__), "icons")
|
||||
|
||||
# load a preview thumbnail of a file and store in the previews collection
|
||||
pcoll.load("my_icon", os.path.join(my_icons_dir, "icon-image.png"), 'IMAGE')
|
||||
|
||||
preview_collections["main"] = pcoll
|
||||
|
||||
bpy.utils.register_class(PreviewsExamplePanel)
|
||||
|
||||
|
||||
def unregister():
|
||||
|
||||
for pcoll in preview_collections.values():
|
||||
bpy.utils.previews.remove(pcoll)
|
||||
preview_collections.clear()
|
||||
|
||||
bpy.utils.unregister_class(PreviewsExamplePanel)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
141
blender-5.2.0/scripts/templates_py/UI/previews_dynamic_enum.py
Normal file
141
blender-5.2.0/scripts/templates_py/UI/previews_dynamic_enum.py
Normal file
@@ -0,0 +1,141 @@
|
||||
# This sample script demonstrates a dynamic EnumProperty with custom icons.
|
||||
# The EnumProperty is populated dynamically with thumbnails of the contents of
|
||||
# a chosen directory in 'enum_previews_from_directory_items'.
|
||||
# Then, the same enum is displayed with different interfaces. Note that the
|
||||
# generated icon previews do not have Blender IDs, which means that they can
|
||||
# not be used with UILayout templates that require IDs,
|
||||
# such as template_list and template_ID_preview.
|
||||
#
|
||||
# Other use cases:
|
||||
# - make a fixed list of enum_items instead of calculating them in a function
|
||||
# - generate isolated thumbnails to use as custom icons in buttons
|
||||
# and menu items
|
||||
#
|
||||
# For custom icons, see the template "ui_previews_custom_icon.py".
|
||||
#
|
||||
# For distributable scripts, it is recommended to place the icons inside the
|
||||
# script directory and access it relative to the py script file for portability:
|
||||
#
|
||||
# os.path.join(os.path.dirname(__file__), "images")
|
||||
|
||||
|
||||
import os
|
||||
import bpy
|
||||
|
||||
|
||||
def enum_previews_from_directory_items(self, context):
|
||||
"""EnumProperty callback"""
|
||||
enum_items = []
|
||||
|
||||
if context is None:
|
||||
return enum_items
|
||||
|
||||
wm = context.window_manager
|
||||
directory = wm.my_previews_dir
|
||||
|
||||
# Get the preview collection (defined in register func).
|
||||
pcoll = preview_collections["main"]
|
||||
|
||||
if directory == pcoll.my_previews_dir:
|
||||
return pcoll.my_previews
|
||||
|
||||
print("Scanning directory:", directory)
|
||||
|
||||
if directory and os.path.exists(directory):
|
||||
# Scan the directory for `*.png` files
|
||||
image_paths = []
|
||||
for fn in os.listdir(directory):
|
||||
if fn.lower().endswith(".png"):
|
||||
image_paths.append(fn)
|
||||
|
||||
for i, name in enumerate(image_paths):
|
||||
# generates a thumbnail preview for a file.
|
||||
filepath = os.path.join(directory, name)
|
||||
icon = pcoll.get(name)
|
||||
if not icon:
|
||||
thumb = pcoll.load(name, filepath, 'IMAGE')
|
||||
else:
|
||||
thumb = pcoll[name]
|
||||
enum_items.append((name, name, "", thumb.icon_id, i))
|
||||
|
||||
pcoll.my_previews = enum_items
|
||||
pcoll.my_previews_dir = directory
|
||||
return pcoll.my_previews
|
||||
|
||||
|
||||
class PreviewsExamplePanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the Object properties window"""
|
||||
bl_label = "Previews Example Panel"
|
||||
bl_idname = "OBJECT_PT_previews"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
wm = context.window_manager
|
||||
|
||||
row = layout.row()
|
||||
row.prop(wm, "my_previews_dir")
|
||||
|
||||
row = layout.row()
|
||||
row.template_icon_view(wm, "my_previews")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(wm, "my_previews")
|
||||
|
||||
|
||||
# We can store multiple preview collections here,
|
||||
# however in this example we only store "main"
|
||||
preview_collections = {}
|
||||
|
||||
|
||||
def register():
|
||||
from bpy.types import WindowManager
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
)
|
||||
|
||||
WindowManager.my_previews_dir = StringProperty(
|
||||
name="Folder Path",
|
||||
subtype='DIR_PATH',
|
||||
default=""
|
||||
)
|
||||
|
||||
WindowManager.my_previews = EnumProperty(
|
||||
items=enum_previews_from_directory_items,
|
||||
)
|
||||
|
||||
# Note that preview collections returned by bpy.utils.previews
|
||||
# are regular Python objects - you can use them to store custom data.
|
||||
#
|
||||
# This is especially useful here, since:
|
||||
# - It avoids us regenerating the whole enum over and over.
|
||||
# - It can store enum_items' strings
|
||||
# (remember you have to keep those strings somewhere in py,
|
||||
# else they get freed and Blender references invalid memory!).
|
||||
import bpy.utils.previews
|
||||
pcoll = bpy.utils.previews.new()
|
||||
pcoll.my_previews_dir = ""
|
||||
pcoll.my_previews = ()
|
||||
|
||||
preview_collections["main"] = pcoll
|
||||
|
||||
bpy.utils.register_class(PreviewsExamplePanel)
|
||||
|
||||
|
||||
def unregister():
|
||||
from bpy.types import WindowManager
|
||||
|
||||
del WindowManager.my_previews
|
||||
|
||||
for pcoll in preview_collections.values():
|
||||
bpy.utils.previews.remove(pcoll)
|
||||
preview_collections.clear()
|
||||
|
||||
bpy.utils.unregister_class(PreviewsExamplePanel)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
91
blender-5.2.0/scripts/templates_py/UI/tool_simple.py
Normal file
91
blender-5.2.0/scripts/templates_py/UI/tool_simple.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# This example adds an object mode tool to the toolbar.
|
||||
# This is just the circle-select and lasso tools tool.
|
||||
import bpy
|
||||
from bpy.types import WorkSpaceTool
|
||||
|
||||
|
||||
class MyTool(WorkSpaceTool):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_context_mode = 'OBJECT'
|
||||
|
||||
# The prefix of the idname should be your add-on name.
|
||||
bl_idname = "my_template.my_circle_select"
|
||||
bl_label = "My Circle Select"
|
||||
bl_description = (
|
||||
"This is a tooltip\n"
|
||||
"with multiple lines"
|
||||
)
|
||||
bl_icon = "ops.generic.select_circle"
|
||||
bl_widget = None
|
||||
bl_keymap = (
|
||||
("view3d.select_circle", {"type": 'LEFTMOUSE', "value": 'PRESS'},
|
||||
{"properties": [("wait_for_input", False)]}),
|
||||
("view3d.select_circle", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'SUB'), ("wait_for_input", False)]}),
|
||||
)
|
||||
|
||||
def draw_settings(context, layout, tool):
|
||||
props = tool.operator_properties("view3d.select_circle")
|
||||
layout.prop(props, "mode")
|
||||
layout.prop(props, "radius")
|
||||
|
||||
|
||||
class MyOtherTool(WorkSpaceTool):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_context_mode = 'OBJECT'
|
||||
|
||||
bl_idname = "my_template.my_other_select"
|
||||
bl_label = "My Lasso Tool Select"
|
||||
bl_description = (
|
||||
"This is a tooltip\n"
|
||||
"with multiple lines"
|
||||
)
|
||||
bl_icon = "ops.generic.select_lasso"
|
||||
bl_widget = None
|
||||
bl_keymap = (
|
||||
("view3d.select_lasso", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("view3d.select_lasso", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'SUB')]}),
|
||||
)
|
||||
|
||||
def draw_settings(context, layout, tool):
|
||||
props = tool.operator_properties("view3d.select_lasso")
|
||||
layout.prop(props, "mode")
|
||||
|
||||
|
||||
class MyWidgetTool(WorkSpaceTool):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_context_mode = 'OBJECT'
|
||||
|
||||
bl_idname = "my_template.my_gizmo_translate"
|
||||
bl_label = "My Gizmo Tool"
|
||||
bl_description = "Short description"
|
||||
bl_icon = "ops.transform.transform"
|
||||
bl_widget = "VIEW3D_GGT_tool_generic_handle_free"
|
||||
bl_widget_properties = [
|
||||
("radius", 75.0),
|
||||
("backdrop_fill_alpha", 0.0),
|
||||
]
|
||||
bl_keymap = (
|
||||
("transform.transform", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
)
|
||||
|
||||
def draw_settings(context, layout, tool):
|
||||
props = tool.operator_properties("transform.transform")
|
||||
layout.prop(props, "mode")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_tool(MyTool, after={"builtin.scale_cage"}, separator=True, group=True)
|
||||
bpy.utils.register_tool(MyOtherTool, after={MyTool.bl_idname})
|
||||
bpy.utils.register_tool(MyWidgetTool, after={MyTool.bl_idname})
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_tool(MyTool)
|
||||
bpy.utils.unregister_tool(MyOtherTool)
|
||||
bpy.utils.unregister_tool(MyWidgetTool)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
Reference in New Issue
Block a user