Compare commits
47 Commits
temp-viewp
...
soc-2020-c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
11aa61274d | ||
![]() |
1b8bc74b1f | ||
![]() |
705acb423b | ||
![]() |
114987ee42 | ||
![]() |
f8ebfd0e88 | ||
![]() |
0dfe6a6a37 | ||
![]() |
fd2d7e7a48 | ||
81aeb7ab08 | |||
![]() |
2772910b32 | ||
![]() |
79d256a06d | ||
![]() |
278b753088 | ||
![]() |
0137777137 | ||
a7e8e509a7 | |||
8da4917156 | |||
![]() |
4279181f10 | ||
![]() |
b1269effa9 | ||
![]() |
ca64458b61 | ||
04ef339f74 | |||
![]() |
1e68909800 | ||
![]() |
0de94b2b62 | ||
![]() |
d225ddec4a | ||
![]() |
8d0a3b5c1c | ||
![]() |
9ca8bf13d5 | ||
![]() |
2ae9183f4b | ||
a1dcb2aa70 | |||
9f60b06c8b | |||
![]() |
48b5c90975 | ||
![]() |
1cd405850c | ||
![]() |
cd610269dc | ||
![]() |
9fe9eb5240 | ||
![]() |
3c9ba5e994 | ||
![]() |
b83e559956 | ||
![]() |
fe0e9900d5 | ||
![]() |
3a519e00c5 | ||
![]() |
2eba146a88 | ||
9c530388ca | |||
![]() |
bf3c22ec55 | ||
![]() |
7f7a7efc62 | ||
52b2901156 | |||
![]() |
8344c0acc5 | ||
![]() |
3229939eae | ||
![]() |
d1921a46ca | ||
![]() |
b997a7cb51 | ||
![]() |
8a661f5dd1 | ||
![]() |
717dfa198c | ||
![]() |
935b518ec7 | ||
![]() |
4e04c9b874 |
Submodule release/datafiles/locale updated: 2b3c19f5f6...2a85baf731
@@ -105,6 +105,7 @@ const UserDef U_default = {
|
|||||||
|
|
||||||
.autoexec_paths = {NULL},
|
.autoexec_paths = {NULL},
|
||||||
.user_menus = {NULL},
|
.user_menus = {NULL},
|
||||||
|
.user_menus_group = {NULL},
|
||||||
|
|
||||||
.keyconfigstr = "blender",
|
.keyconfigstr = "blender",
|
||||||
.undosteps = 32,
|
.undosteps = 32,
|
||||||
@@ -234,5 +235,9 @@ const UserDef U_default = {
|
|||||||
.runtime =
|
.runtime =
|
||||||
{
|
{
|
||||||
.is_dirty = 0,
|
.is_dirty = 0,
|
||||||
|
|
||||||
|
.um_space_select = 1,
|
||||||
|
.um_context_select = 0,
|
||||||
|
.um_item_select = NULL,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Submodule release/scripts/addons updated: 49c39f59fb...5d33d1a1c2
Submodule release/scripts/addons_contrib updated: a52733b58d...f2f4a8b3bf
294
release/scripts/modules/rna_user_menus_ui.py
Normal file
294
release/scripts/modules/rna_user_menus_ui.py
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
"draw_user_menus",
|
||||||
|
)
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.app.translations import pgettext_iface as iface_
|
||||||
|
from bpy.app.translations import contexts as i18n_contexts
|
||||||
|
|
||||||
|
def _indented_layout(layout, level):
|
||||||
|
indentpx = 16
|
||||||
|
if level == 0:
|
||||||
|
level = 0.0001 # Tweak so that a percentage of 0 won't split by half
|
||||||
|
indent = level * indentpx / bpy.context.region.width
|
||||||
|
|
||||||
|
split = layout.split(factor=indent)
|
||||||
|
col = split.column()
|
||||||
|
col = split.column()
|
||||||
|
return col
|
||||||
|
|
||||||
|
def get_keymap(context, idname, ensure):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
if not idname:
|
||||||
|
idname = um.active_group.idname
|
||||||
|
|
||||||
|
for km in context.window_manager.keyconfigs.user.keymaps:
|
||||||
|
for kmi in km.keymap_items:
|
||||||
|
if kmi.idname == "wm.call_user_menu":
|
||||||
|
if kmi.properties.name == idname:
|
||||||
|
return kmi
|
||||||
|
if ensure:
|
||||||
|
km = context.window_manager.keyconfigs.user.keymaps['Window']
|
||||||
|
kmi = km.keymap_items.new("wm.call_user_menu",'NONE', 'ANY', shift=False, ctrl=False, alt=False)
|
||||||
|
kmi.properties.idname = idname
|
||||||
|
kmi.active = True
|
||||||
|
return kmi
|
||||||
|
|
||||||
|
def draw_button(context, box, item, index):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
name = item.name
|
||||||
|
if name == "":
|
||||||
|
name = " "
|
||||||
|
item.is_selected = item == um.active_item
|
||||||
|
col = box.column(align=True)
|
||||||
|
row = col.row(align=True)
|
||||||
|
if item.type == "SEPARATOR":
|
||||||
|
name = "___________"
|
||||||
|
#icons = bpy.types.UILayout.bl_rna.functions["prop"].parameters["icon"].enum_items.keys()
|
||||||
|
#selected_icon = icons[item.icon]
|
||||||
|
row.prop(item, "is_selected", icon=item.icon, text=name, toggle=1)
|
||||||
|
if item.type == "SUBMENU":
|
||||||
|
sm = item.get_submenu()
|
||||||
|
if um.active_group.type == "PIE" and index >= 0:
|
||||||
|
row.operator("preferences.pie_menuitem_add", text="", icon='ADD').index = index
|
||||||
|
row.operator("preferences.menuitem_remove", text="", icon='REMOVE')
|
||||||
|
row.operator("preferences.menuitem_up", text="", icon='TRIA_UP')
|
||||||
|
row.operator("preferences.menuitem_down", text="", icon='TRIA_DOWN')
|
||||||
|
sub_box = col.box()
|
||||||
|
sub_box = sub_box.column(align=True)
|
||||||
|
draw_item(context, sub_box, sm.items_list)
|
||||||
|
|
||||||
|
def draw_item(context, box, items):
|
||||||
|
for umi in items:
|
||||||
|
draw_button(context, box, umi, -1)
|
||||||
|
|
||||||
|
def draw_item_box(context, row):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
box_line = row.box()
|
||||||
|
box_col = box_line.column(align=True)
|
||||||
|
|
||||||
|
has_item = um.has_item()
|
||||||
|
if not has_item:
|
||||||
|
box_col.label(text="none")
|
||||||
|
else:
|
||||||
|
draw_item(context, box_col, um.get_current_menu().menu_items)
|
||||||
|
|
||||||
|
row = row.split(factor=0.9, align=True)
|
||||||
|
col = row.column(align=True)
|
||||||
|
|
||||||
|
col.operator("preferences.menuitem_add", text="", icon='ADD').index = -1
|
||||||
|
col.operator("preferences.menuitem_remove", text="", icon='REMOVE')
|
||||||
|
col.operator("preferences.menuitem_up", text="", icon='TRIA_UP')
|
||||||
|
col.operator("preferences.menuitem_down", text="", icon='TRIA_DOWN')
|
||||||
|
row.separator()
|
||||||
|
|
||||||
|
def draw_pie_item(context, col, items, label, index):
|
||||||
|
row = col.row()
|
||||||
|
row.label(text=label)
|
||||||
|
draw_button(context, row, items, index)
|
||||||
|
|
||||||
|
def draw_pie(context, row):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
cm = um.get_current_menu()
|
||||||
|
if not cm:
|
||||||
|
return
|
||||||
|
col = row.column()
|
||||||
|
draw_pie_item(context, col, cm.menu_items[0], "Left : ", 0)
|
||||||
|
draw_pie_item(context, col, cm.menu_items[1], "Right : ", 1)
|
||||||
|
draw_pie_item(context, col, cm.menu_items[2], "Down : ", 2)
|
||||||
|
draw_pie_item(context, col, cm.menu_items[3], "Up : ", 3)
|
||||||
|
draw_pie_item(context, col, cm.menu_items[4], "Upper left : ", 4)
|
||||||
|
draw_pie_item(context, col, cm.menu_items[5], "Upper right : ", 5)
|
||||||
|
draw_pie_item(context, col, cm.menu_items[6], "Lower left : ", 6)
|
||||||
|
draw_pie_item(context, col, cm.menu_items[7], "Lower right : ", 7)
|
||||||
|
row.separator()
|
||||||
|
|
||||||
|
|
||||||
|
def draw_item_editor(context, row):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
col = row.column()
|
||||||
|
|
||||||
|
has_item = um.has_item()
|
||||||
|
current = um.active_item
|
||||||
|
if not has_item:
|
||||||
|
col.label(text="No item in this list.")
|
||||||
|
col.label(text="Add one or choose another list to get started")
|
||||||
|
elif current:
|
||||||
|
col.prop(current, "type")
|
||||||
|
if (current.type != "SEPARATOR"):
|
||||||
|
rowsub = col.row(align=True)
|
||||||
|
rowsub.prop(current, "icon", icon=current.icon, text="")
|
||||||
|
col.prop(current, "name")
|
||||||
|
if (current.type == "OPERATOR"):
|
||||||
|
umi_op = current.get_operator()
|
||||||
|
col.prop(umi_op, "operator")
|
||||||
|
box = col.box()
|
||||||
|
box.template_user_menu_item_properties(umi_op)
|
||||||
|
if (current.type == "MENU"):
|
||||||
|
umi_pm = current.get_menu()
|
||||||
|
col.prop(umi_pm, "id_name", text="ID name")
|
||||||
|
if (current.type == "PROPERTY"):
|
||||||
|
umi_prop = current.get_property()
|
||||||
|
col.prop(umi_prop, "id_name")
|
||||||
|
col.prop(umi_prop, "context")
|
||||||
|
else:
|
||||||
|
col.label(text="No item selected.")
|
||||||
|
|
||||||
|
def draw_user_menu_preference_expanded(context, layout, kmi, map_type):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
box = layout.box()
|
||||||
|
sub = box.row()
|
||||||
|
|
||||||
|
if kmi:
|
||||||
|
if map_type not in {'TEXTINPUT', 'TIMER'}:
|
||||||
|
sub = box.column()
|
||||||
|
subrow = sub.row(align=True)
|
||||||
|
|
||||||
|
if map_type == 'KEYBOARD':
|
||||||
|
subrow.prop(kmi, "type", text="", event=True)
|
||||||
|
subrow.prop(kmi, "value", text="")
|
||||||
|
subrow_repeat = subrow.row(align=True)
|
||||||
|
subrow_repeat.active = kmi.value in {'ANY', 'PRESS'}
|
||||||
|
subrow_repeat.prop(kmi, "repeat", text="Repeat")
|
||||||
|
elif map_type in {'MOUSE', 'NDOF'}:
|
||||||
|
subrow.prop(kmi, "type", text="")
|
||||||
|
subrow.prop(kmi, "value", text="")
|
||||||
|
|
||||||
|
subrow = sub.row()
|
||||||
|
subrow.scale_x = 0.75
|
||||||
|
subrow.prop(kmi, "any", toggle=True)
|
||||||
|
subrow.prop(kmi, "shift", toggle=True)
|
||||||
|
subrow.prop(kmi, "ctrl", toggle=True)
|
||||||
|
subrow.prop(kmi, "alt", toggle=True)
|
||||||
|
subrow.prop(kmi, "oskey", text="Cmd", toggle=True)
|
||||||
|
subrow.prop(kmi, "key_modifier", text="", event=True)
|
||||||
|
else:
|
||||||
|
sub.label(text="No key set")
|
||||||
|
|
||||||
|
def draw_user_menu_preference(context, layout):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
umg = um.active_group
|
||||||
|
kmi = get_keymap(context, None, False)
|
||||||
|
map_type = None
|
||||||
|
|
||||||
|
box = layout.box()
|
||||||
|
row = box.row()
|
||||||
|
|
||||||
|
row.prop(um, "expanded", text="", emboss=False)
|
||||||
|
|
||||||
|
qf = um.menus[0]
|
||||||
|
if umg != qf:
|
||||||
|
row.prop(umg, "name")
|
||||||
|
pie_text = "List"
|
||||||
|
if umg.type == "PIE":
|
||||||
|
pie_text = "Pie"
|
||||||
|
row.prop(umg, "type", text=pie_text, expand=True)
|
||||||
|
if kmi:
|
||||||
|
row.prop(kmi, "map_type", text="")
|
||||||
|
map_type = kmi.map_type
|
||||||
|
if map_type == 'KEYBOARD':
|
||||||
|
row.prop(kmi, "type", text="", full_event=True)
|
||||||
|
elif map_type == 'MOUSE':
|
||||||
|
row.prop(kmi, "type", text="", full_event=True)
|
||||||
|
elif map_type == 'NDOF':
|
||||||
|
row.prop(kmi, "type", text="", full_event=True)
|
||||||
|
elif map_type == 'TWEAK':
|
||||||
|
subrow = row.row()
|
||||||
|
subrow.prop(kmi, "type", text="")
|
||||||
|
subrow.prop(kmi, "value", text="")
|
||||||
|
elif map_type == 'TIMER':
|
||||||
|
row.prop(kmi, "type", text="")
|
||||||
|
else:
|
||||||
|
row.label()
|
||||||
|
|
||||||
|
if um.expanded:
|
||||||
|
draw_user_menu_preference_expanded(context=context, layout=box, kmi=kmi, map_type=map_type)
|
||||||
|
|
||||||
|
|
||||||
|
def menu_id(context, umg):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for item in um.menus:
|
||||||
|
if item == umg:
|
||||||
|
return i
|
||||||
|
i = i + 1
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
def draw_user_menus(context, layout):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
if not um.active_group:
|
||||||
|
um.active_group = um.menus[0]
|
||||||
|
|
||||||
|
split = layout.split(factor=0.4)
|
||||||
|
|
||||||
|
row = split.row()
|
||||||
|
|
||||||
|
rowsub = row.row(align=True)
|
||||||
|
rowsub.menu("USERPREF_MT_menu_select", text=um.active_group.name)
|
||||||
|
rowsub.operator("preferences.usermenus_add", text="", icon='ADD')
|
||||||
|
rowsub.operator("preferences.usermenus_remove", text="", icon='REMOVE')
|
||||||
|
|
||||||
|
rowsub = split.row(align=True)
|
||||||
|
rowsub.prop(um, "space_selected", text="")
|
||||||
|
|
||||||
|
rowsub = split.row(align=True)
|
||||||
|
rowsub.prop(um, "context_selected", text="")
|
||||||
|
|
||||||
|
#rowsub = split.row(align=True)
|
||||||
|
#rowsub.operator("preferences.keyconfig_import", text="", icon='IMPORT')
|
||||||
|
#rowsub.operator("preferences.keyconfig_export", text="", icon='EXPORT')
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.separator()
|
||||||
|
|
||||||
|
draw_user_menu_preference(context=context, layout=row)
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.separator()
|
||||||
|
|
||||||
|
if um.active_group.type == "PIE":
|
||||||
|
draw_pie(context=context, row=row)
|
||||||
|
else:
|
||||||
|
draw_item_box(context=context, row=row)
|
||||||
|
draw_item_editor(context=context, row=row)
|
||||||
|
|
||||||
|
row.separator()
|
||||||
|
|
@@ -157,6 +157,8 @@ def op_menu(menu, kmi_args):
|
|||||||
def op_menu_pie(menu, kmi_args):
|
def op_menu_pie(menu, kmi_args):
|
||||||
return ("wm.call_menu_pie", kmi_args, {"properties": [("name", menu)]})
|
return ("wm.call_menu_pie", kmi_args, {"properties": [("name", menu)]})
|
||||||
|
|
||||||
|
def op_user_menu(menu, kmi_args):
|
||||||
|
return ("wm.call_user_menu", kmi_args, {"properties": [("name", menu)]})
|
||||||
|
|
||||||
def op_panel(menu, kmi_args, kmi_data=()):
|
def op_panel(menu, kmi_args, kmi_data=()):
|
||||||
return ("wm.call_panel", kmi_args, {"properties": [("name", menu), *kmi_data]})
|
return ("wm.call_panel", kmi_args, {"properties": [("name", menu), *kmi_data]})
|
||||||
@@ -407,7 +409,7 @@ def km_window(params):
|
|||||||
("wm.quit_blender", {"type": 'Q', "value": 'PRESS', "ctrl": True}, None),
|
("wm.quit_blender", {"type": 'Q', "value": 'PRESS', "ctrl": True}, None),
|
||||||
|
|
||||||
# Quick menu and toolbar
|
# Quick menu and toolbar
|
||||||
op_menu("SCREEN_MT_user_menu", {"type": 'Q', "value": 'PRESS'}),
|
op_user_menu("QUICK_FAVORITES", {"type": 'Q', "value": 'PRESS'}),
|
||||||
|
|
||||||
# Fast editor switching
|
# Fast editor switching
|
||||||
*(
|
*(
|
||||||
|
@@ -67,6 +67,8 @@ def op_menu(menu, kmi_args):
|
|||||||
def op_menu_pie(menu, kmi_args):
|
def op_menu_pie(menu, kmi_args):
|
||||||
return ("wm.call_menu_pie", kmi_args, {"properties": [("name", menu)]})
|
return ("wm.call_menu_pie", kmi_args, {"properties": [("name", menu)]})
|
||||||
|
|
||||||
|
def op_user_menu(menu, kmi_args):
|
||||||
|
return ("wm.call_user_menu", kmi_args, {"properties": [("name", menu)]})
|
||||||
|
|
||||||
def op_panel(menu, kmi_args, kmi_data=()):
|
def op_panel(menu, kmi_args, kmi_data=()):
|
||||||
return ("wm.call_panel", kmi_args, {"properties": [("name", menu), *kmi_data]})
|
return ("wm.call_panel", kmi_args, {"properties": [("name", menu), *kmi_data]})
|
||||||
@@ -210,7 +212,7 @@ def km_window(params):
|
|||||||
("wm.quit_blender", {"type": 'Q', "value": 'PRESS', "ctrl": True}, None),
|
("wm.quit_blender", {"type": 'Q', "value": 'PRESS', "ctrl": True}, None),
|
||||||
|
|
||||||
# Quick menu and toolbar
|
# Quick menu and toolbar
|
||||||
op_menu("SCREEN_MT_user_menu", {"type": 'TAB', "value": 'PRESS', "shift": True}),
|
op_user_menu("QUICK_FAVORITES", {"type": 'Q', "value": 'PRESS'}),
|
||||||
|
|
||||||
# NDOF settings
|
# NDOF settings
|
||||||
op_panel("USERPREF_PT_ndof_settings", {"type": 'NDOF_BUTTON_MENU', "value": 'PRESS'}),
|
op_panel("USERPREF_PT_ndof_settings", {"type": 'NDOF_BUTTON_MENU', "value": 'PRESS'}),
|
||||||
|
@@ -602,7 +602,6 @@ class AddPresetOperator(AddPresetBase, Operator):
|
|||||||
prefix, suffix = operator.split("_OT_", 1)
|
prefix, suffix = operator.split("_OT_", 1)
|
||||||
return os.path.join("operator", "%s.%s" % (prefix.lower(), suffix))
|
return os.path.join("operator", "%s.%s" % (prefix.lower(), suffix))
|
||||||
|
|
||||||
|
|
||||||
class WM_MT_operator_presets(Menu):
|
class WM_MT_operator_presets(Menu):
|
||||||
bl_label = "Operator Presets"
|
bl_label = "Operator Presets"
|
||||||
|
|
||||||
|
@@ -51,6 +51,8 @@ def module_filesystem_remove(path_base, module_name):
|
|||||||
|
|
||||||
# This duplicates shutil.copytree from Python 3.8, with the new dirs_exist_ok
|
# This duplicates shutil.copytree from Python 3.8, with the new dirs_exist_ok
|
||||||
# argument that we need. Once we upgrade to 3.8 we can remove this.
|
# argument that we need. Once we upgrade to 3.8 we can remove this.
|
||||||
|
|
||||||
|
|
||||||
def _preferences_copytree(entries, src, dst):
|
def _preferences_copytree(entries, src, dst):
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
@@ -85,11 +87,13 @@ def _preferences_copytree(entries, src, dst):
|
|||||||
raise Error(errors)
|
raise Error(errors)
|
||||||
return dst
|
return dst
|
||||||
|
|
||||||
|
|
||||||
def preferences_copytree(src, dst):
|
def preferences_copytree(src, dst):
|
||||||
import os
|
import os
|
||||||
with os.scandir(src) as entries:
|
with os.scandir(src) as entries:
|
||||||
return _preferences_copytree(entries=entries, src=src, dst=dst)
|
return _preferences_copytree(entries=entries, src=src, dst=dst)
|
||||||
|
|
||||||
|
|
||||||
class PREFERENCES_OT_keyconfig_activate(Operator):
|
class PREFERENCES_OT_keyconfig_activate(Operator):
|
||||||
bl_idname = "preferences.keyconfig_activate"
|
bl_idname = "preferences.keyconfig_activate"
|
||||||
bl_label = "Activate Keyconfig"
|
bl_label = "Activate Keyconfig"
|
||||||
@@ -241,7 +245,8 @@ class PREFERENCES_OT_keyconfig_import(Operator):
|
|||||||
|
|
||||||
config_name = basename(self.filepath)
|
config_name = basename(self.filepath)
|
||||||
|
|
||||||
path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
|
path = bpy.utils.user_resource(
|
||||||
|
'SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
|
||||||
path = os.path.join(path, config_name)
|
path = os.path.join(path, config_name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -460,7 +465,8 @@ class PREFERENCES_OT_addon_enable(Operator):
|
|||||||
err_str = traceback.format_exc()
|
err_str = traceback.format_exc()
|
||||||
print(err_str)
|
print(err_str)
|
||||||
|
|
||||||
mod = addon_utils.enable(self.module, default_set=True, handle_error=err_cb)
|
mod = addon_utils.enable(
|
||||||
|
self.module, default_set=True, handle_error=err_cb)
|
||||||
|
|
||||||
if mod:
|
if mod:
|
||||||
info = addon_utils.module_bl_info(mod)
|
info = addon_utils.module_bl_info(mod)
|
||||||
@@ -544,7 +550,8 @@ class PREFERENCES_OT_theme_install(Operator):
|
|||||||
|
|
||||||
xmlfile = self.filepath
|
xmlfile = self.filepath
|
||||||
|
|
||||||
path_themes = bpy.utils.user_resource('SCRIPTS', "presets/interface_theme", create=True)
|
path_themes = bpy.utils.user_resource(
|
||||||
|
'SCRIPTS', "presets/interface_theme", create=True)
|
||||||
|
|
||||||
if not path_themes:
|
if not path_themes:
|
||||||
self.report({'ERROR'}, "Failed to get themes path")
|
self.report({'ERROR'}, "Failed to get themes path")
|
||||||
@@ -554,7 +561,8 @@ class PREFERENCES_OT_theme_install(Operator):
|
|||||||
|
|
||||||
if not self.overwrite:
|
if not self.overwrite:
|
||||||
if os.path.exists(path_dest):
|
if os.path.exists(path_dest):
|
||||||
self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
|
self.report(
|
||||||
|
{'WARNING'}, "File already installed to %r\n" % path_dest)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -638,7 +646,8 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||||||
|
|
||||||
if self.target == 'DEFAULT':
|
if self.target == 'DEFAULT':
|
||||||
# don't use bpy.utils.script_paths("addons") because we may not be able to write to it.
|
# don't use bpy.utils.script_paths("addons") because we may not be able to write to it.
|
||||||
path_addons = bpy.utils.user_resource('SCRIPTS', "addons", create=True)
|
path_addons = bpy.utils.user_resource(
|
||||||
|
'SCRIPTS', "addons", create=True)
|
||||||
else:
|
else:
|
||||||
path_addons = context.preferences.filepaths.script_directory
|
path_addons = context.preferences.filepaths.script_directory
|
||||||
if path_addons:
|
if path_addons:
|
||||||
@@ -661,7 +670,8 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||||||
pyfile_dir = os.path.dirname(pyfile)
|
pyfile_dir = os.path.dirname(pyfile)
|
||||||
for addon_path in addon_utils.paths():
|
for addon_path in addon_utils.paths():
|
||||||
if os.path.samefile(pyfile_dir, addon_path):
|
if os.path.samefile(pyfile_dir, addon_path):
|
||||||
self.report({'ERROR'}, "Source file is in the add-on search path: %r" % addon_path)
|
self.report(
|
||||||
|
{'ERROR'}, "Source file is in the add-on search path: %r" % addon_path)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
del addon_path
|
del addon_path
|
||||||
del pyfile_dir
|
del pyfile_dir
|
||||||
@@ -684,7 +694,8 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||||||
for f in file_to_extract.namelist():
|
for f in file_to_extract.namelist():
|
||||||
path_dest = os.path.join(path_addons, os.path.basename(f))
|
path_dest = os.path.join(path_addons, os.path.basename(f))
|
||||||
if os.path.exists(path_dest):
|
if os.path.exists(path_dest):
|
||||||
self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
|
self.report(
|
||||||
|
{'WARNING'}, "File already installed to %r\n" % path_dest)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
try: # extract the file to "addons"
|
try: # extract the file to "addons"
|
||||||
@@ -699,7 +710,8 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||||||
if self.overwrite:
|
if self.overwrite:
|
||||||
module_filesystem_remove(path_addons, os.path.basename(pyfile))
|
module_filesystem_remove(path_addons, os.path.basename(pyfile))
|
||||||
elif os.path.exists(path_dest):
|
elif os.path.exists(path_dest):
|
||||||
self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
|
self.report(
|
||||||
|
{'WARNING'}, "File already installed to %r\n" % path_dest)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
# if not compressed file just copy into the addon path
|
# if not compressed file just copy into the addon path
|
||||||
@@ -709,7 +721,8 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
addons_new = {mod.__name__ for mod in addon_utils.modules()} - addons_old
|
addons_new = {mod.__name__ for mod in addon_utils.modules()} - \
|
||||||
|
addons_old
|
||||||
addons_new.discard("modules")
|
addons_new.discard("modules")
|
||||||
|
|
||||||
# disable any addons we may have enabled previously and removed.
|
# disable any addons we may have enabled previously and removed.
|
||||||
@@ -779,7 +792,8 @@ class PREFERENCES_OT_addon_remove(Operator):
|
|||||||
|
|
||||||
path, isdir = PREFERENCES_OT_addon_remove.path_from_addon(self.module)
|
path, isdir = PREFERENCES_OT_addon_remove.path_from_addon(self.module)
|
||||||
if path is None:
|
if path is None:
|
||||||
self.report({'WARNING'}, "Add-on path %r could not be found" % path)
|
self.report(
|
||||||
|
{'WARNING'}, "Add-on path %r could not be found" % path)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
# in case its enabled
|
# in case its enabled
|
||||||
@@ -925,9 +939,11 @@ class PREFERENCES_OT_app_template_install(Operator):
|
|||||||
module_filesystem_remove(path_app_templates, f)
|
module_filesystem_remove(path_app_templates, f)
|
||||||
else:
|
else:
|
||||||
for f in file_to_extract.namelist():
|
for f in file_to_extract.namelist():
|
||||||
path_dest = os.path.join(path_app_templates, os.path.basename(f))
|
path_dest = os.path.join(
|
||||||
|
path_app_templates, os.path.basename(f))
|
||||||
if os.path.exists(path_dest):
|
if os.path.exists(path_dest):
|
||||||
self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
|
self.report(
|
||||||
|
{'WARNING'}, "File already installed to %r\n" % path_dest)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
try: # extract the file to "bl_app_templates_user"
|
try: # extract the file to "bl_app_templates_user"
|
||||||
@@ -941,7 +957,8 @@ class PREFERENCES_OT_app_template_install(Operator):
|
|||||||
self.report({'WARNING'}, "Expected a zip-file %r\n" % filepath)
|
self.report({'WARNING'}, "Expected a zip-file %r\n" % filepath)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
app_templates_new = set(os.listdir(path_app_templates)) - app_templates_old
|
app_templates_new = set(os.listdir(
|
||||||
|
path_app_templates)) - app_templates_old
|
||||||
|
|
||||||
# in case a new module path was created to install this addon.
|
# in case a new module path was created to install this addon.
|
||||||
bpy.utils.refresh_script_paths()
|
bpy.utils.refresh_script_paths()
|
||||||
@@ -1001,14 +1018,17 @@ class PREFERENCES_OT_studiolight_install(Operator):
|
|||||||
prefs = context.preferences
|
prefs = context.preferences
|
||||||
|
|
||||||
path_studiolights = os.path.join("studiolights", self.type.lower())
|
path_studiolights = os.path.join("studiolights", self.type.lower())
|
||||||
path_studiolights = bpy.utils.user_resource('DATAFILES', path_studiolights, create=True)
|
path_studiolights = bpy.utils.user_resource(
|
||||||
|
'DATAFILES', path_studiolights, create=True)
|
||||||
if not path_studiolights:
|
if not path_studiolights:
|
||||||
self.report({'ERROR'}, "Failed to create Studio Light path")
|
self.report({'ERROR'}, "Failed to create Studio Light path")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
for e in self.files:
|
for e in self.files:
|
||||||
shutil.copy(os.path.join(self.directory, e.name), path_studiolights)
|
shutil.copy(os.path.join(self.directory, e.name),
|
||||||
prefs.studio_lights.load(os.path.join(path_studiolights, e.name), self.type)
|
path_studiolights)
|
||||||
|
prefs.studio_lights.load(os.path.join(
|
||||||
|
path_studiolights, e.name), self.type)
|
||||||
|
|
||||||
# print message
|
# print message
|
||||||
msg = (
|
msg = (
|
||||||
@@ -1047,7 +1067,8 @@ class PREFERENCES_OT_studiolight_new(Operator):
|
|||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
filename = bpy.path.ensure_ext(self.filename, ".sl")
|
filename = bpy.path.ensure_ext(self.filename, ".sl")
|
||||||
|
|
||||||
path_studiolights = bpy.utils.user_resource('DATAFILES', os.path.join("studiolights", "studio"), create=True)
|
path_studiolights = bpy.utils.user_resource(
|
||||||
|
'DATAFILES', os.path.join("studiolights", "studio"), create=True)
|
||||||
if not path_studiolights:
|
if not path_studiolights:
|
||||||
self.report({'ERROR'}, "Failed to get Studio Light path")
|
self.report({'ERROR'}, "Failed to get Studio Light path")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
@@ -1060,7 +1081,8 @@ class PREFERENCES_OT_studiolight_new(Operator):
|
|||||||
else:
|
else:
|
||||||
for studio_light in prefs.studio_lights:
|
for studio_light in prefs.studio_lights:
|
||||||
if studio_light.name == filename:
|
if studio_light.name == filename:
|
||||||
bpy.ops.preferences.studiolight_uninstall(index=studio_light.index)
|
bpy.ops.preferences.studiolight_uninstall(
|
||||||
|
index=studio_light.index)
|
||||||
|
|
||||||
prefs.studio_lights.new(path=filepath_final)
|
prefs.studio_lights.new(path=filepath_final)
|
||||||
|
|
||||||
@@ -1076,7 +1098,8 @@ class PREFERENCES_OT_studiolight_new(Operator):
|
|||||||
def draw(self, _context):
|
def draw(self, _context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
if self.ask_overide:
|
if self.ask_overide:
|
||||||
layout.label(text="Warning, file already exists. Overwrite existing file?")
|
layout.label(
|
||||||
|
text="Warning, file already exists. Overwrite existing file?")
|
||||||
else:
|
else:
|
||||||
layout.prop(self, "filename")
|
layout.prop(self, "filename")
|
||||||
|
|
||||||
@@ -1141,6 +1164,184 @@ class PREFERENCES_OT_studiolight_show(Operator):
|
|||||||
bpy.ops.screen.userpref_show('INVOKE_DEFAULT')
|
bpy.ops.screen.userpref_show('INVOKE_DEFAULT')
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# User Menus Operators
|
||||||
|
|
||||||
|
class PREFERENCES_OT_usermenus_select(Operator):
|
||||||
|
bl_idname = "preferences.usermenus_select"
|
||||||
|
bl_label = "select user menu to edit"
|
||||||
|
|
||||||
|
index: IntProperty()
|
||||||
|
|
||||||
|
def execute(self, _context):
|
||||||
|
prefs = _context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for umg in um.menus:
|
||||||
|
if i == self.index:
|
||||||
|
um.set_group(new_group=umg)
|
||||||
|
return {'FINISHED'}
|
||||||
|
i = i + 1
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
class PREFERENCES_OT_usermenus_add(Operator):
|
||||||
|
bl_idname = "preferences.usermenus_add"
|
||||||
|
bl_label = "add an user menus group"
|
||||||
|
|
||||||
|
def execute(self, _context):
|
||||||
|
prefs = _context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
um.add_group()
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
class PREFERENCES_OT_usermenus_remove(Operator):
|
||||||
|
bl_idname = "preferences.usermenus_remove"
|
||||||
|
bl_label = "remove an user menus group"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
if um.active_group.idname == "QUICK_FAVORITES":
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, _context):
|
||||||
|
prefs = _context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
um.remove_group()
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
class PREFERENCES_OT_menuitem_add(Operator):
|
||||||
|
"""Add user menu item"""
|
||||||
|
bl_idname = "preferences.menuitem_add"
|
||||||
|
bl_label = "Add User Menu Item"
|
||||||
|
|
||||||
|
index: IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
um.item_add(index=self.index)
|
||||||
|
context.preferences.is_dirty = True
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class PREFERENCES_OT_menuitem_remove(Operator):
|
||||||
|
"""Remove user menu item"""
|
||||||
|
bl_idname = "preferences.menuitem_remove"
|
||||||
|
bl_label = "Remove User Menu Item"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
can_remove = um.active_item
|
||||||
|
um_type = um.active_group.type
|
||||||
|
|
||||||
|
if um_type == "PIE" and can_remove:
|
||||||
|
if not can_remove.parent:
|
||||||
|
return False
|
||||||
|
return can_remove
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
um.item_remove()
|
||||||
|
context.preferences.is_dirty = True
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class PREFERENCES_OT_menuitem_up(Operator):
|
||||||
|
"""move up an user menu item"""
|
||||||
|
bl_idname = "preferences.menuitem_up"
|
||||||
|
bl_label = "Move Up An User Menu Item"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
current = um.active_item
|
||||||
|
um_type = um.active_group.type
|
||||||
|
if not current:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if um_type == "PIE":
|
||||||
|
if not current.parent:
|
||||||
|
return False
|
||||||
|
prev_item = current.prev
|
||||||
|
if prev_item:
|
||||||
|
return True
|
||||||
|
if current.parent.item.parent:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
prev_item = current.prev
|
||||||
|
if prev_item or current.parent:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
um.item_move(up=True)
|
||||||
|
context.preferences.is_dirty = True
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class PREFERENCES_OT_menuitem_down(Operator):
|
||||||
|
"""move up an user menu item"""
|
||||||
|
bl_idname = "preferences.menuitem_down"
|
||||||
|
bl_label = "Move Up An User Menu Item"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
um_type = um.active_group.type
|
||||||
|
current = um.active_item
|
||||||
|
if not current:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if um_type == "PIE":
|
||||||
|
if not current.parent:
|
||||||
|
return False
|
||||||
|
next_item = current.next
|
||||||
|
if next_item:
|
||||||
|
return True
|
||||||
|
if current.parent.item.parent:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
next_item = current.next
|
||||||
|
if next_item or current.parent:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
um.item_move(up=False)
|
||||||
|
context.preferences.is_dirty = True
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
class PREFERENCES_OT_pie_menuitem_add(Operator):
|
||||||
|
"""Add user menu item"""
|
||||||
|
bl_idname = "preferences.pie_menuitem_add"
|
||||||
|
bl_label = "Add User Menu Item"
|
||||||
|
|
||||||
|
index: IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
um.pie_item_add(index=self.index)
|
||||||
|
context.preferences.is_dirty = True
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
PREFERENCES_OT_addon_disable,
|
PREFERENCES_OT_addon_disable,
|
||||||
@@ -1167,4 +1368,12 @@ classes = (
|
|||||||
PREFERENCES_OT_studiolight_uninstall,
|
PREFERENCES_OT_studiolight_uninstall,
|
||||||
PREFERENCES_OT_studiolight_copy_settings,
|
PREFERENCES_OT_studiolight_copy_settings,
|
||||||
PREFERENCES_OT_studiolight_show,
|
PREFERENCES_OT_studiolight_show,
|
||||||
|
PREFERENCES_OT_usermenus_select,
|
||||||
|
PREFERENCES_OT_usermenus_add,
|
||||||
|
PREFERENCES_OT_usermenus_remove,
|
||||||
|
PREFERENCES_OT_menuitem_add,
|
||||||
|
PREFERENCES_OT_menuitem_remove,
|
||||||
|
PREFERENCES_OT_menuitem_up,
|
||||||
|
PREFERENCES_OT_menuitem_down,
|
||||||
|
PREFERENCES_OT_pie_menuitem_add,
|
||||||
)
|
)
|
||||||
|
@@ -2633,6 +2633,36 @@ class WM_OT_drop_blend_file(Operator):
|
|||||||
col.operator("wm.link", text="Link...", icon='LINK_BLEND').filepath = self.filepath
|
col.operator("wm.link", text="Link...", icon='LINK_BLEND').filepath = self.filepath
|
||||||
col.operator("wm.append", text="Append...", icon='APPEND_BLEND').filepath = self.filepath
|
col.operator("wm.append", text="Append...", icon='APPEND_BLEND').filepath = self.filepath
|
||||||
|
|
||||||
|
class WM_OT_call_user_menu(Operator):
|
||||||
|
bl_idname = "wm.call_user_menu"
|
||||||
|
bl_label = "display user menu"
|
||||||
|
|
||||||
|
name: StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def draw_menu(self, menu, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
umg = um.get_group(idname=self.name)
|
||||||
|
|
||||||
|
layout = menu.layout
|
||||||
|
if umg.type == "PIE":
|
||||||
|
layout = layout.menu_pie()
|
||||||
|
um.draw_menu(context=context, layout=layout, menu=umg)
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
wm = context.window_manager
|
||||||
|
umg = um.get_group(idname=self.name)
|
||||||
|
|
||||||
|
if umg.type == "PIE":
|
||||||
|
wm.popup_menu_pie(draw_func=self.draw_menu, title=umg.name, event=event)
|
||||||
|
else:
|
||||||
|
wm.popup_menu(self.draw_menu, title=umg.name)
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
WM_OT_context_collection_boolean_set,
|
WM_OT_context_collection_boolean_set,
|
||||||
@@ -2677,4 +2707,5 @@ classes = (
|
|||||||
WM_OT_batch_rename,
|
WM_OT_batch_rename,
|
||||||
WM_MT_splash,
|
WM_MT_splash,
|
||||||
WM_MT_splash_about,
|
WM_MT_splash_about,
|
||||||
|
WM_OT_call_user_menu,
|
||||||
)
|
)
|
||||||
|
@@ -1684,8 +1684,37 @@ class USERPREF_PT_keymap(KeymapPanel, Panel):
|
|||||||
# Keymap Settings
|
# Keymap Settings
|
||||||
draw_keymaps(context, layout)
|
draw_keymaps(context, layout)
|
||||||
|
|
||||||
# print("runtime", time.time() - start)
|
# -----------------------------------------------------------------------------
|
||||||
|
# Custom Menu Editor Panels
|
||||||
|
|
||||||
|
class UserMenusPanel:
|
||||||
|
bl_space_type = 'PREFERENCES'
|
||||||
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_context = "user_menus"
|
||||||
|
|
||||||
|
class USERPREF_MT_menu_select(Menu):
|
||||||
|
bl_label = "Menus group select"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
prefs = context.preferences
|
||||||
|
um = prefs.user_menus
|
||||||
|
|
||||||
|
layout = self.layout
|
||||||
|
index = 0
|
||||||
|
for umg in um.menus:
|
||||||
|
layout.operator("preferences.usermenus_select", text=umg.name).index = index
|
||||||
|
index = index + 1
|
||||||
|
|
||||||
|
|
||||||
|
class USERPREF_PT_user_menus(UserMenusPanel, Panel):
|
||||||
|
bl_label = "user_menus"
|
||||||
|
bl_options = {'HIDE_HEADER'}
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
from rna_user_menus_ui import draw_user_menus
|
||||||
|
|
||||||
|
layout = self.layout
|
||||||
|
draw_user_menus(context, layout)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Add-On Panels
|
# Add-On Panels
|
||||||
@@ -2278,6 +2307,8 @@ classes = (
|
|||||||
USERPREF_PT_navigation_fly_walk_gravity,
|
USERPREF_PT_navigation_fly_walk_gravity,
|
||||||
|
|
||||||
USERPREF_PT_keymap,
|
USERPREF_PT_keymap,
|
||||||
|
USERPREF_MT_menu_select,
|
||||||
|
USERPREF_PT_user_menus,
|
||||||
USERPREF_PT_addons,
|
USERPREF_PT_addons,
|
||||||
|
|
||||||
USERPREF_PT_studiolight_lights,
|
USERPREF_PT_studiolight_lights,
|
||||||
|
@@ -27,7 +27,16 @@ extern "C" {
|
|||||||
struct ListBase;
|
struct ListBase;
|
||||||
struct bUserMenu;
|
struct bUserMenu;
|
||||||
struct bUserMenuItem;
|
struct bUserMenuItem;
|
||||||
|
struct wmWindowManager;
|
||||||
|
struct bUserMenusGroup;
|
||||||
|
|
||||||
|
void BKE_blender_user_menu_free_list(struct ListBase *lb);
|
||||||
|
void BKE_blender_user_menus_group_idname_update(struct bUserMenusGroup *umg);
|
||||||
|
void BKE_blender_user_menus_group_idname_update_keymap(struct wmWindowManager *wm,
|
||||||
|
const char *old,
|
||||||
|
const char *new);
|
||||||
|
struct bUserMenusGroup *BKE_blender_user_menus_group_new(const char *name);
|
||||||
|
struct bUserMenusGroup *BKE_blender_user_menus_group_find(struct ListBase *lb, const char *idname);
|
||||||
struct bUserMenu *BKE_blender_user_menu_find(struct ListBase *lb,
|
struct bUserMenu *BKE_blender_user_menu_find(struct ListBase *lb,
|
||||||
char space_type,
|
char space_type,
|
||||||
const char *context);
|
const char *context);
|
||||||
@@ -38,6 +47,7 @@ struct bUserMenu *BKE_blender_user_menu_ensure(struct ListBase *lb,
|
|||||||
struct bUserMenuItem *BKE_blender_user_menu_item_add(struct ListBase *lb, int type);
|
struct bUserMenuItem *BKE_blender_user_menu_item_add(struct ListBase *lb, int type);
|
||||||
void BKE_blender_user_menu_item_free(struct bUserMenuItem *umi);
|
void BKE_blender_user_menu_item_free(struct bUserMenuItem *umi);
|
||||||
void BKE_blender_user_menu_item_free_list(struct ListBase *lb);
|
void BKE_blender_user_menu_item_free_list(struct ListBase *lb);
|
||||||
|
struct bUserMenusGroup *BKU_blender_user_menu_default(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -255,6 +255,7 @@ struct ViewLayer *CTX_data_view_layer(const bContext *C);
|
|||||||
struct RenderEngineType *CTX_data_engine_type(const bContext *C);
|
struct RenderEngineType *CTX_data_engine_type(const bContext *C);
|
||||||
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
|
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
|
||||||
|
|
||||||
|
const char **CTX_data_list_mode_string(void);
|
||||||
const char *CTX_data_mode_string(const bContext *C);
|
const char *CTX_data_mode_string(const bContext *C);
|
||||||
enum eContextObjectMode CTX_data_mode_enum_ex(const struct Object *obedit,
|
enum eContextObjectMode CTX_data_mode_enum_ex(const struct Object *obedit,
|
||||||
const struct Object *ob,
|
const struct Object *ob,
|
||||||
|
@@ -238,11 +238,15 @@ static void userdef_free_keyconfig_prefs(UserDef *userdef)
|
|||||||
|
|
||||||
static void userdef_free_user_menus(UserDef *userdef)
|
static void userdef_free_user_menus(UserDef *userdef)
|
||||||
{
|
{
|
||||||
for (bUserMenu *um = userdef->user_menus.first, *um_next; um; um = um_next) {
|
for (bUserMenusGroup *umg = userdef->user_menus_group.first, *umg_next; umg; umg = umg_next) {
|
||||||
|
umg_next = umg->next;
|
||||||
|
for (bUserMenu *um = umg->menus.first, *um_next; um; um = um_next) {
|
||||||
um_next = um->next;
|
um_next = um->next;
|
||||||
BKE_blender_user_menu_item_free_list(&um->items);
|
BKE_blender_user_menu_item_free_list(&um->items);
|
||||||
MEM_freeN(um);
|
MEM_freeN(um);
|
||||||
}
|
}
|
||||||
|
MEM_freeN(umg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void userdef_free_addons(UserDef *userdef)
|
static void userdef_free_addons(UserDef *userdef)
|
||||||
|
@@ -26,12 +26,97 @@
|
|||||||
|
|
||||||
#include "BLI_listbase.h"
|
#include "BLI_listbase.h"
|
||||||
#include "BLI_string.h"
|
#include "BLI_string.h"
|
||||||
|
#include "BLI_string_utils.h"
|
||||||
|
|
||||||
#include "DNA_userdef_types.h"
|
#include "DNA_userdef_types.h"
|
||||||
|
#include "DNA_windowmanager_types.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
|
||||||
#include "BKE_blender_user_menu.h"
|
#include "BKE_blender_user_menu.h"
|
||||||
#include "BKE_idprop.h"
|
#include "BKE_idprop.h"
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Menu group
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
void BKE_blender_user_menu_free_list(ListBase *lb)
|
||||||
|
{
|
||||||
|
for (bUserMenu *um = lb->first, *um_next; um; um = um_next) {
|
||||||
|
um_next = um->next;
|
||||||
|
BKE_blender_user_menu_item_free_list(&um->items);
|
||||||
|
MEM_freeN(um);
|
||||||
|
}
|
||||||
|
BLI_listbase_clear(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
bUserMenusGroup *BKE_blender_user_menus_group_find(ListBase *lb, const char *idname)
|
||||||
|
{
|
||||||
|
LISTBASE_FOREACH (bUserMenusGroup *, umg, lb) {
|
||||||
|
if ((STREQ(idname, umg->idname))) {
|
||||||
|
return umg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BKE_blender_user_menus_group_idname_update(bUserMenusGroup *umg)
|
||||||
|
{
|
||||||
|
char name[64];
|
||||||
|
|
||||||
|
STRNCPY(name, umg->name);
|
||||||
|
for (int i = 0; name[i]; i++) {
|
||||||
|
if (name[i] == ' ')
|
||||||
|
name[i] = '_';
|
||||||
|
if (name[i] >= 'a' && name[i] <= 'z')
|
||||||
|
name[i] += 'A' - 'a';
|
||||||
|
}
|
||||||
|
STRNCPY(umg->idname, name);
|
||||||
|
BLI_uniquename(&U.user_menus_group,
|
||||||
|
umg,
|
||||||
|
umg->idname,
|
||||||
|
'_',
|
||||||
|
offsetof(bUserMenusGroup, idname),
|
||||||
|
sizeof(umg->idname));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BKE_blender_user_menus_group_idname_update_keymap(wmWindowManager *wm,
|
||||||
|
const char *old,
|
||||||
|
const char *new)
|
||||||
|
{
|
||||||
|
wmKeyConfig *kc;
|
||||||
|
wmKeyMap *km;
|
||||||
|
|
||||||
|
for (kc = wm->keyconfigs.first; kc; kc = kc->next) {
|
||||||
|
for (km = kc->keymaps.first; km; km = km->next) {
|
||||||
|
wmKeyMapItem *kmi;
|
||||||
|
for (kmi = km->items.first; kmi; kmi = kmi->next) {
|
||||||
|
if (STREQ(kmi->idname, "WM_OT_call_user_menu")) {
|
||||||
|
IDProperty *idp = IDP_GetPropertyFromGroup(kmi->properties, "name");
|
||||||
|
char *index = IDP_String(idp);
|
||||||
|
if (STREQ(index, old)) {
|
||||||
|
IDP_AssignString(idp, new, 64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bUserMenusGroup *BKE_blender_user_menus_group_new(const char *name)
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = MEM_mallocN(sizeof(*umg), __func__);
|
||||||
|
STRNCPY(umg->name, name);
|
||||||
|
umg->type = 0;
|
||||||
|
umg->prev = NULL;
|
||||||
|
umg->next = NULL;
|
||||||
|
BLI_listbase_clear(&umg->menus);
|
||||||
|
BKE_blender_user_menus_group_idname_update(umg);
|
||||||
|
return umg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Menu Type
|
/** \name Menu Type
|
||||||
* \{ */
|
* \{ */
|
||||||
@@ -50,8 +135,10 @@ bUserMenu *BKE_blender_user_menu_ensure(ListBase *lb, char space_type, const cha
|
|||||||
{
|
{
|
||||||
bUserMenu *um = BKE_blender_user_menu_find(lb, space_type, context);
|
bUserMenu *um = BKE_blender_user_menu_find(lb, space_type, context);
|
||||||
if (um == NULL) {
|
if (um == NULL) {
|
||||||
|
|
||||||
um = MEM_callocN(sizeof(bUserMenu), __func__);
|
um = MEM_callocN(sizeof(bUserMenu), __func__);
|
||||||
um->space_type = space_type;
|
um->space_type = space_type;
|
||||||
|
BLI_listbase_clear(&um->items);
|
||||||
STRNCPY(um->context, context);
|
STRNCPY(um->context, context);
|
||||||
BLI_addhead(lb, um);
|
BLI_addhead(lb, um);
|
||||||
}
|
}
|
||||||
@@ -80,6 +167,9 @@ bUserMenuItem *BKE_blender_user_menu_item_add(ListBase *lb, int type)
|
|||||||
else if (type == USER_MENU_TYPE_PROP) {
|
else if (type == USER_MENU_TYPE_PROP) {
|
||||||
size = sizeof(bUserMenuItem_Prop);
|
size = sizeof(bUserMenuItem_Prop);
|
||||||
}
|
}
|
||||||
|
else if (type == USER_MENU_TYPE_SUBMENU) {
|
||||||
|
size = sizeof(bUserMenuItem_SubMenu);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
size = sizeof(bUserMenuItem);
|
size = sizeof(bUserMenuItem);
|
||||||
BLI_assert(0);
|
BLI_assert(0);
|
||||||
@@ -87,6 +177,8 @@ bUserMenuItem *BKE_blender_user_menu_item_add(ListBase *lb, int type)
|
|||||||
|
|
||||||
bUserMenuItem *umi = MEM_callocN(size, __func__);
|
bUserMenuItem *umi = MEM_callocN(size, __func__);
|
||||||
umi->type = type;
|
umi->type = type;
|
||||||
|
umi->icon = 0;
|
||||||
|
if (lb)
|
||||||
BLI_addtail(lb, umi);
|
BLI_addtail(lb, umi);
|
||||||
return umi;
|
return umi;
|
||||||
}
|
}
|
||||||
@@ -99,6 +191,10 @@ void BKE_blender_user_menu_item_free(bUserMenuItem *umi)
|
|||||||
IDP_FreeProperty(umi_op->prop);
|
IDP_FreeProperty(umi_op->prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (umi->type == USER_MENU_TYPE_SUBMENU) {
|
||||||
|
bUserMenuItem_SubMenu *umi_sm = (bUserMenuItem_SubMenu *)umi;
|
||||||
|
BKE_blender_user_menu_item_free_list(&umi_sm->items);
|
||||||
|
}
|
||||||
MEM_freeN(umi);
|
MEM_freeN(umi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,3 +206,19 @@ void BKE_blender_user_menu_item_free_list(ListBase *lb)
|
|||||||
}
|
}
|
||||||
BLI_listbase_clear(lb);
|
BLI_listbase_clear(lb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Default Menu
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
bUserMenusGroup *BKU_blender_user_menu_default(void)
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = MEM_mallocN(sizeof(*umg), __func__);
|
||||||
|
STRNCPY(umg->name, "Quick Favorites");
|
||||||
|
STRNCPY(umg->idname, "QUICK_FAVORITES");
|
||||||
|
umg->type = 0;
|
||||||
|
umg->prev = NULL;
|
||||||
|
umg->next = NULL;
|
||||||
|
BLI_listbase_clear(&umg->menus);
|
||||||
|
return umg;
|
||||||
|
}
|
@@ -57,6 +57,7 @@
|
|||||||
#include "BKE_screen.h"
|
#include "BKE_screen.h"
|
||||||
#include "BKE_studiolight.h"
|
#include "BKE_studiolight.h"
|
||||||
#include "BKE_workspace.h"
|
#include "BKE_workspace.h"
|
||||||
|
#include "BKE_blender_user_menu.h"
|
||||||
|
|
||||||
#include "BLO_readfile.h"
|
#include "BLO_readfile.h"
|
||||||
#include "BLO_writefile.h"
|
#include "BLO_writefile.h"
|
||||||
@@ -614,6 +615,13 @@ UserDef *BKE_blendfile_userdef_from_defaults(void)
|
|||||||
BLI_addtail(&userdef->themes, btheme);
|
BLI_addtail(&userdef->themes, btheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* default user menus. */
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = BKU_blender_user_menu_default();
|
||||||
|
BLI_addtail(&userdef->user_menus_group, umg);
|
||||||
|
userdef->runtime.umg_select = umg;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_PYTHON_SECURITY
|
#ifdef WITH_PYTHON_SECURITY
|
||||||
/* use alternative setting for security nuts
|
/* use alternative setting for security nuts
|
||||||
* otherwise we'd need to patch the binary blob - startup.blend.c */
|
* otherwise we'd need to patch the binary blob - startup.blend.c */
|
||||||
|
@@ -1151,6 +1151,11 @@ const char *CTX_data_mode_string(const bContext *C)
|
|||||||
return data_mode_strings[CTX_data_mode_enum(C)];
|
return data_mode_strings[CTX_data_mode_enum(C)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char **CTX_data_list_mode_string(void)
|
||||||
|
{
|
||||||
|
return data_mode_strings;
|
||||||
|
}
|
||||||
|
|
||||||
void CTX_data_scene_set(bContext *C, Scene *scene)
|
void CTX_data_scene_set(bContext *C, Scene *scene)
|
||||||
{
|
{
|
||||||
C->data.scene = scene;
|
C->data.scene = scene;
|
||||||
|
@@ -114,6 +114,7 @@
|
|||||||
#include "BKE_action.h"
|
#include "BKE_action.h"
|
||||||
#include "BKE_anim_data.h"
|
#include "BKE_anim_data.h"
|
||||||
#include "BKE_armature.h"
|
#include "BKE_armature.h"
|
||||||
|
#include "BKE_blender_user_menu.h"
|
||||||
#include "BKE_brush.h"
|
#include "BKE_brush.h"
|
||||||
#include "BKE_collection.h"
|
#include "BKE_collection.h"
|
||||||
#include "BKE_colortools.h"
|
#include "BKE_colortools.h"
|
||||||
@@ -159,6 +160,8 @@
|
|||||||
#include "BKE_volume.h"
|
#include "BKE_volume.h"
|
||||||
#include "BKE_workspace.h"
|
#include "BKE_workspace.h"
|
||||||
|
|
||||||
|
#include "BKE_blender_user_menu.h"
|
||||||
|
|
||||||
#include "DRW_engine.h"
|
#include "DRW_engine.h"
|
||||||
|
|
||||||
#include "DEG_depsgraph.h"
|
#include "DEG_depsgraph.h"
|
||||||
@@ -8897,6 +8900,26 @@ static void direct_link_keymapitem(BlendDataReader *reader, wmKeyMapItem *kmi)
|
|||||||
kmi->flag &= ~KMI_UPDATE;
|
kmi->flag &= ~KMI_UPDATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void read_usermenuitems(BlendDataReader *reader,
|
||||||
|
ListBase *lb,
|
||||||
|
bUserMenuItem_SubMenu *parent)
|
||||||
|
{
|
||||||
|
LISTBASE_FOREACH (bUserMenuItem *, umi, lb) {
|
||||||
|
umi->parent = parent;
|
||||||
|
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
||||||
|
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
||||||
|
BLO_read_data_address(reader, &umi_op->prop);
|
||||||
|
IDP_BlendDataRead(reader, &umi_op->prop);
|
||||||
|
}
|
||||||
|
if (umi->type == USER_MENU_TYPE_SUBMENU) {
|
||||||
|
bUserMenuItem_SubMenu *umi_sm = (bUserMenuItem_SubMenu *)umi;
|
||||||
|
BLI_listbase_clear(&umi_sm->items);
|
||||||
|
BLO_read_list(reader, &umi_sm->items);
|
||||||
|
read_usermenuitems(reader, &umi_sm->items, umi_sm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
||||||
{
|
{
|
||||||
UserDef *user;
|
UserDef *user;
|
||||||
@@ -8918,6 +8941,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|||||||
BLO_read_list(reader, &user->user_menus);
|
BLO_read_list(reader, &user->user_menus);
|
||||||
BLO_read_list(reader, &user->addons);
|
BLO_read_list(reader, &user->addons);
|
||||||
BLO_read_list(reader, &user->autoexec_paths);
|
BLO_read_list(reader, &user->autoexec_paths);
|
||||||
|
BLO_read_list(reader, &user->user_menus_group);
|
||||||
|
|
||||||
LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) {
|
LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) {
|
||||||
keymap->modal_items = NULL;
|
keymap->modal_items = NULL;
|
||||||
@@ -8951,13 +8975,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|||||||
|
|
||||||
LISTBASE_FOREACH (bUserMenu *, um, &user->user_menus) {
|
LISTBASE_FOREACH (bUserMenu *, um, &user->user_menus) {
|
||||||
BLO_read_list(reader, &um->items);
|
BLO_read_list(reader, &um->items);
|
||||||
LISTBASE_FOREACH (bUserMenuItem *, umi, &um->items) {
|
read_usermenuitems(reader, &um->items, NULL);
|
||||||
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
|
||||||
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
|
||||||
BLO_read_data_address(reader, &umi_op->prop);
|
|
||||||
IDP_BlendDataRead(reader, &umi_op->prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LISTBASE_FOREACH (bAddon *, addon, &user->addons) {
|
LISTBASE_FOREACH (bAddon *, addon, &user->addons) {
|
||||||
@@ -8965,6 +8983,23 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|||||||
IDP_BlendDataRead(reader, &addon->prop);
|
IDP_BlendDataRead(reader, &addon->prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (bUserMenusGroup *, umg, &user->user_menus_group) {
|
||||||
|
BLO_read_list(reader, &umg->menus);
|
||||||
|
BKE_blender_user_menus_group_idname_update(umg);
|
||||||
|
LISTBASE_FOREACH (bUserMenu *, um, &umg->menus) {
|
||||||
|
BLO_read_list(reader, &um->items);
|
||||||
|
read_usermenuitems(reader, &um->items, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user->user_menus.first != NULL && user->user_menus_group.first == NULL) {
|
||||||
|
bUserMenusGroup *umg = BKU_blender_user_menu_default();
|
||||||
|
BLI_addtail(&user->user_menus_group, umg);
|
||||||
|
user->runtime.umg_select = umg;
|
||||||
|
umg->menus = user->user_menus;
|
||||||
|
BLI_listbase_clear(&user->user_menus);
|
||||||
|
}
|
||||||
|
|
||||||
// XXX
|
// XXX
|
||||||
user->uifonts.first = user->uifonts.last = NULL;
|
user->uifonts.first = user->uifonts.last = NULL;
|
||||||
|
|
||||||
@@ -8976,6 +9011,10 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|||||||
/* Clear runtime data. */
|
/* Clear runtime data. */
|
||||||
user->runtime.is_dirty = false;
|
user->runtime.is_dirty = false;
|
||||||
user->edit_studio_light = 0;
|
user->edit_studio_light = 0;
|
||||||
|
user->runtime.um_space_select = 1;
|
||||||
|
user->runtime.um_context_select = 1;
|
||||||
|
user->runtime.um_item_select = NULL;
|
||||||
|
user->runtime.umg_select = user->user_menus_group.first;
|
||||||
|
|
||||||
/* free fd->datamap again */
|
/* free fd->datamap again */
|
||||||
oldnewmap_clear(fd->datamap);
|
oldnewmap_clear(fd->datamap);
|
||||||
|
@@ -980,7 +980,37 @@ static void write_keymapitem(BlendWriter *writer, const wmKeyMapItem *kmi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_usermenuitems(BlendWriter *writer, const ListBase *lb)
|
||||||
|
{
|
||||||
|
LISTBASE_FOREACH (const bUserMenuItem *, umi, lb) {
|
||||||
|
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
||||||
|
const bUserMenuItem_Op *umi_op = (const bUserMenuItem_Op *)umi;
|
||||||
|
BLO_write_struct(writer, bUserMenuItem_Op, umi_op);
|
||||||
|
if (umi_op->prop) {
|
||||||
|
IDP_BlendWrite(writer, umi_op->prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (umi->type == USER_MENU_TYPE_MENU) {
|
||||||
|
const bUserMenuItem_Menu *umi_mt = (const bUserMenuItem_Menu *)umi;
|
||||||
|
BLO_write_struct(writer, bUserMenuItem_Menu, umi_mt);
|
||||||
|
}
|
||||||
|
else if (umi->type == USER_MENU_TYPE_PROP) {
|
||||||
|
const bUserMenuItem_Prop *umi_pr = (const bUserMenuItem_Prop *)umi;
|
||||||
|
BLO_write_struct(writer, bUserMenuItem_Prop, umi_pr);
|
||||||
|
}
|
||||||
|
else if (umi->type == USER_MENU_TYPE_SUBMENU) {
|
||||||
|
const bUserMenuItem_SubMenu *umi_sm = (const bUserMenuItem_SubMenu *)umi;
|
||||||
|
BLO_write_struct(writer, bUserMenuItem_SubMenu, umi_sm);
|
||||||
|
write_usermenuitems(writer, &umi_sm->items);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLO_write_struct(writer, bUserMenuItem, umi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void write_userdef(BlendWriter *writer, const UserDef *userdef)
|
static void write_userdef(BlendWriter *writer, const UserDef *userdef)
|
||||||
|
|
||||||
{
|
{
|
||||||
writestruct(writer->wd, USER, UserDef, 1, userdef);
|
writestruct(writer->wd, USER, UserDef, 1, userdef);
|
||||||
|
|
||||||
@@ -1013,30 +1043,6 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LISTBASE_FOREACH (const bUserMenu *, um, &userdef->user_menus) {
|
|
||||||
BLO_write_struct(writer, bUserMenu, um);
|
|
||||||
LISTBASE_FOREACH (const bUserMenuItem *, umi, &um->items) {
|
|
||||||
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
|
||||||
const bUserMenuItem_Op *umi_op = (const bUserMenuItem_Op *)umi;
|
|
||||||
BLO_write_struct(writer, bUserMenuItem_Op, umi_op);
|
|
||||||
if (umi_op->prop) {
|
|
||||||
IDP_BlendWrite(writer, umi_op->prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (umi->type == USER_MENU_TYPE_MENU) {
|
|
||||||
const bUserMenuItem_Menu *umi_mt = (const bUserMenuItem_Menu *)umi;
|
|
||||||
BLO_write_struct(writer, bUserMenuItem_Menu, umi_mt);
|
|
||||||
}
|
|
||||||
else if (umi->type == USER_MENU_TYPE_PROP) {
|
|
||||||
const bUserMenuItem_Prop *umi_pr = (const bUserMenuItem_Prop *)umi;
|
|
||||||
BLO_write_struct(writer, bUserMenuItem_Prop, umi_pr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BLO_write_struct(writer, bUserMenuItem, umi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LISTBASE_FOREACH (const bAddon *, bext, &userdef->addons) {
|
LISTBASE_FOREACH (const bAddon *, bext, &userdef->addons) {
|
||||||
BLO_write_struct(writer, bAddon, bext);
|
BLO_write_struct(writer, bAddon, bext);
|
||||||
if (bext->prop) {
|
if (bext->prop) {
|
||||||
@@ -1048,6 +1054,14 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef)
|
|||||||
BLO_write_struct(writer, bPathCompare, path_cmp);
|
BLO_write_struct(writer, bPathCompare, path_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (const bUserMenusGroup *, umg, &userdef->user_menus_group) {
|
||||||
|
BLO_write_struct(writer, bUserMenusGroup, umg);
|
||||||
|
LISTBASE_FOREACH (const bUserMenu *, um, &umg->menus) {
|
||||||
|
BLO_write_struct(writer, bUserMenu, um);
|
||||||
|
write_usermenuitems(writer, &um->items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LISTBASE_FOREACH (const uiStyle *, style, &userdef->uistyles) {
|
LISTBASE_FOREACH (const uiStyle *, style, &userdef->uistyles) {
|
||||||
BLO_write_struct(writer, uiStyle, style);
|
BLO_write_struct(writer, uiStyle, style);
|
||||||
}
|
}
|
||||||
|
@@ -374,8 +374,12 @@ bool ED_operator_camera(struct bContext *C);
|
|||||||
|
|
||||||
/* screen_user_menu.c */
|
/* screen_user_menu.c */
|
||||||
|
|
||||||
bUserMenu **ED_screen_user_menus_find(const struct bContext *C, uint *r_len);
|
struct bUserMenusGroup *ED_screen_user_menus_group_find(int id);
|
||||||
struct bUserMenu *ED_screen_user_menu_ensure(struct bContext *C);
|
struct bUserMenu **ED_screen_user_menus_find_menu(const struct bContext *C,
|
||||||
|
uint *r_len,
|
||||||
|
struct bUserMenusGroup *umg);
|
||||||
|
struct bUserMenu **ED_screen_user_menus_find(const struct bContext *C, uint *r_len, int id);
|
||||||
|
struct bUserMenu *ED_screen_user_menu_ensure(struct bContext *C, int id);
|
||||||
|
|
||||||
struct bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(struct ListBase *lb,
|
struct bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(struct ListBase *lb,
|
||||||
const struct wmOperatorType *ot,
|
const struct wmOperatorType *ot,
|
||||||
@@ -396,7 +400,8 @@ void ED_screen_user_menu_item_add_operator(struct ListBase *lb,
|
|||||||
void ED_screen_user_menu_item_add_menu(struct ListBase *lb,
|
void ED_screen_user_menu_item_add_menu(struct ListBase *lb,
|
||||||
const char *ui_name,
|
const char *ui_name,
|
||||||
const struct MenuType *mt);
|
const struct MenuType *mt);
|
||||||
void ED_screen_user_menu_item_add_prop(ListBase *lb,
|
void ED_screen_user_menu_item_add_prop(struct bContext *C,
|
||||||
|
ListBase *lb,
|
||||||
const char *ui_name,
|
const char *ui_name,
|
||||||
const char *context_data_path,
|
const char *context_data_path,
|
||||||
const char *prop_id,
|
const char *prop_id,
|
||||||
@@ -404,6 +409,14 @@ void ED_screen_user_menu_item_add_prop(ListBase *lb,
|
|||||||
|
|
||||||
void ED_screen_user_menu_item_remove(struct ListBase *lb, struct bUserMenuItem *umi);
|
void ED_screen_user_menu_item_remove(struct ListBase *lb, struct bUserMenuItem *umi);
|
||||||
void ED_screen_user_menu_register(void);
|
void ED_screen_user_menu_register(void);
|
||||||
|
bool screen_user_menu_draw_items(const struct bContext *C,
|
||||||
|
struct uiLayout *layout,
|
||||||
|
struct ListBase *lb,
|
||||||
|
char type);
|
||||||
|
void screen_user_menu_draw_begin(struct bContext *C,
|
||||||
|
struct uiLayout *layout,
|
||||||
|
char type,
|
||||||
|
struct bUserMenusGroup *umg);
|
||||||
|
|
||||||
/* Cache display helpers */
|
/* Cache display helpers */
|
||||||
|
|
||||||
|
@@ -2113,6 +2113,7 @@ void uiTemplateCacheFile(uiLayout *layout,
|
|||||||
const struct bContext *C,
|
const struct bContext *C,
|
||||||
struct PointerRNA *ptr,
|
struct PointerRNA *ptr,
|
||||||
const char *propname);
|
const char *propname);
|
||||||
|
void uiTemplateUserMenuItemProperties(uiLayout *layout, PointerRNA *ptr);
|
||||||
|
|
||||||
/* Default UIList class name, keep in sync with its declaration in bl_ui/__init__.py */
|
/* Default UIList class name, keep in sync with its declaration in bl_ui/__init__.py */
|
||||||
#define UI_UL_DEFAULT_CLASS_NAME "UI_UL_list"
|
#define UI_UL_DEFAULT_CLASS_NAME "UI_UL_list"
|
||||||
|
@@ -437,7 +437,8 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
|||||||
}
|
}
|
||||||
const char *prop_id = RNA_property_identifier(but->rnaprop);
|
const char *prop_id = RNA_property_identifier(but->rnaprop);
|
||||||
/* Note, ignore 'drawstr', use property idname always. */
|
/* Note, ignore 'drawstr', use property idname always. */
|
||||||
ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex);
|
ED_screen_user_menu_item_add_prop(
|
||||||
|
C, &um->items, "", member_id_data_path, prop_id, but->rnaindex);
|
||||||
if (data_path) {
|
if (data_path) {
|
||||||
MEM_freeN((void *)data_path);
|
MEM_freeN((void *)data_path);
|
||||||
}
|
}
|
||||||
@@ -453,7 +454,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
|
|||||||
static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *UNUSED(arg2))
|
static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *UNUSED(arg2))
|
||||||
{
|
{
|
||||||
uiBut *but = arg1;
|
uiBut *but = arg1;
|
||||||
bUserMenu *um = ED_screen_user_menu_ensure(C);
|
bUserMenu *um = ED_screen_user_menu_ensure(C, 0);
|
||||||
U.runtime.is_dirty = true;
|
U.runtime.is_dirty = true;
|
||||||
ui_but_user_menu_add(C, but, um);
|
ui_but_user_menu_add(C, but, um);
|
||||||
}
|
}
|
||||||
@@ -983,7 +984,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
|
|||||||
bool item_found = false;
|
bool item_found = false;
|
||||||
|
|
||||||
uint um_array_len;
|
uint um_array_len;
|
||||||
bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len);
|
bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len, 0);
|
||||||
for (int um_index = 0; um_index < um_array_len; um_index++) {
|
for (int um_index = 0; um_index < um_array_len; um_index++) {
|
||||||
bUserMenu *um = um_array[um_index];
|
bUserMenu *um = um_array[um_index];
|
||||||
if (um == NULL) {
|
if (um == NULL) {
|
||||||
|
@@ -7390,3 +7390,80 @@ void uiTemplateFileSelectPath(uiLayout *layout, bContext *C, FileSelectParams *p
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Keymap Template
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
static void template_user_menu_item_properties(uiLayout *layout,
|
||||||
|
const char *title,
|
||||||
|
PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
uiLayout *flow, *box, *row;
|
||||||
|
|
||||||
|
uiItemS(layout);
|
||||||
|
|
||||||
|
if (title) {
|
||||||
|
uiItemL(layout, title, ICON_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
flow = uiLayoutColumnFlow(layout, 2, false);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
RNA_STRUCT_BEGIN_SKIP_RNA_TYPE (ptr, prop) {
|
||||||
|
const bool is_set = RNA_property_is_set(ptr, prop);
|
||||||
|
uiBut *but;
|
||||||
|
|
||||||
|
// recurse for nested properties
|
||||||
|
if (RNA_property_type(prop) == PROP_POINTER) {
|
||||||
|
PointerRNA propptr = RNA_property_pointer_get(ptr, prop);
|
||||||
|
|
||||||
|
if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) {
|
||||||
|
const char *name = RNA_property_ui_name(prop);
|
||||||
|
template_user_menu_item_properties(layout, name, &propptr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
box = uiLayoutBox(flow);
|
||||||
|
uiLayoutSetActive(box, is_set);
|
||||||
|
row = uiLayoutRow(box, false);
|
||||||
|
|
||||||
|
// property value
|
||||||
|
uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
|
||||||
|
|
||||||
|
if (is_set) {
|
||||||
|
// unset operator
|
||||||
|
uiBlock *block = uiLayoutGetBlock(row);
|
||||||
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||||
|
but = uiDefIconButO(block,
|
||||||
|
UI_BTYPE_BUT,
|
||||||
|
"UI_OT_unset_property_button",
|
||||||
|
WM_OP_EXEC_DEFAULT,
|
||||||
|
ICON_X,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
UI_UNIT_X,
|
||||||
|
UI_UNIT_Y,
|
||||||
|
NULL);
|
||||||
|
but->rnapoin = *ptr;
|
||||||
|
but->rnaprop = prop;
|
||||||
|
UI_block_emboss_set(block, UI_EMBOSS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RNA_STRUCT_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiTemplateUserMenuItemProperties(uiLayout *layout, PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
PointerRNA propptr = RNA_pointer_get(ptr, "prop");
|
||||||
|
|
||||||
|
if (propptr.data) {
|
||||||
|
uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
|
||||||
|
|
||||||
|
WM_operator_properties_sanitize(&propptr, false);
|
||||||
|
template_user_menu_item_properties(layout, NULL, &propptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
@@ -67,10 +67,23 @@ static const char *screen_menu_context_string(const bContext *C, const SpaceLink
|
|||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Menu Type
|
/** \name Menu Group
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
bUserMenu **ED_screen_user_menus_find(const bContext *C, uint *r_len)
|
bUserMenusGroup *ED_screen_user_menus_group_find(int id)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
LISTBASE_FOREACH (bUserMenusGroup *, umg, &U.user_menus_group) {
|
||||||
|
if (index == id)
|
||||||
|
return umg;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
bUserMenu **ED_screen_user_menus_find_menu(const bContext *C, uint *r_len, bUserMenusGroup *umg)
|
||||||
{
|
{
|
||||||
SpaceLink *sl = CTX_wm_space_data(C);
|
SpaceLink *sl = CTX_wm_space_data(C);
|
||||||
|
|
||||||
@@ -83,23 +96,33 @@ bUserMenu **ED_screen_user_menus_find(const bContext *C, uint *r_len)
|
|||||||
const char *context = screen_menu_context_string(C, sl);
|
const char *context = screen_menu_context_string(C, sl);
|
||||||
uint array_len = 3;
|
uint array_len = 3;
|
||||||
bUserMenu **um_array = MEM_calloc_arrayN(array_len, sizeof(*um_array), __func__);
|
bUserMenu **um_array = MEM_calloc_arrayN(array_len, sizeof(*um_array), __func__);
|
||||||
um_array[0] = BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context);
|
um_array[0] = BKE_blender_user_menu_find(&umg->menus, sl->spacetype, context);
|
||||||
um_array[1] = (sl->spacetype != SPACE_TOPBAR) ?
|
um_array[1] = (sl->spacetype != SPACE_TOPBAR) ?
|
||||||
BKE_blender_user_menu_find(&U.user_menus, SPACE_TOPBAR, context_mode) :
|
BKE_blender_user_menu_find(&umg->menus, SPACE_TOPBAR, context_mode) :
|
||||||
NULL;
|
NULL;
|
||||||
um_array[2] = (sl->spacetype == SPACE_VIEW3D) ?
|
um_array[2] = (sl->spacetype == SPACE_VIEW3D) ?
|
||||||
BKE_blender_user_menu_find(&U.user_menus, SPACE_PROPERTIES, context_mode) :
|
BKE_blender_user_menu_find(&umg->menus, SPACE_PROPERTIES, context_mode) :
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
*r_len = array_len;
|
*r_len = array_len;
|
||||||
return um_array;
|
return um_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
bUserMenu *ED_screen_user_menu_ensure(bContext *C)
|
bUserMenu **ED_screen_user_menus_find(const bContext *C, uint *r_len, int id)
|
||||||
{
|
{
|
||||||
|
bUserMenusGroup *umg = ED_screen_user_menus_group_find(id);
|
||||||
|
if (!umg)
|
||||||
|
return NULL;
|
||||||
|
return ED_screen_user_menus_find_menu(C, r_len, umg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bUserMenu *ED_screen_user_menu_ensure(bContext *C, int id)
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = ED_screen_user_menus_group_find(id);
|
||||||
|
if (!umg)
|
||||||
|
return NULL;
|
||||||
SpaceLink *sl = CTX_wm_space_data(C);
|
SpaceLink *sl = CTX_wm_space_data(C);
|
||||||
const char *context = screen_menu_context_string(C, sl);
|
const char *context = screen_menu_context_string(C, sl);
|
||||||
return BKE_blender_user_menu_ensure(&U.user_menus, sl->spacetype, context);
|
return BKE_blender_user_menu_ensure(&umg->menus, sl->spacetype, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@@ -169,6 +192,9 @@ void ED_screen_user_menu_item_add_operator(ListBase *lb,
|
|||||||
STRNCPY(umi_op->item.ui_name, ui_name);
|
STRNCPY(umi_op->item.ui_name, ui_name);
|
||||||
}
|
}
|
||||||
STRNCPY(umi_op->op_idname, ot->idname);
|
STRNCPY(umi_op->op_idname, ot->idname);
|
||||||
|
umi_op->ptr = NULL;
|
||||||
|
umi_op->prop = NULL;
|
||||||
|
WM_operator_properties_alloc(&(umi_op->ptr), &(umi_op->prop), ot->idname);
|
||||||
umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL;
|
umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +208,8 @@ void ED_screen_user_menu_item_add_menu(ListBase *lb, const char *ui_name, const
|
|||||||
STRNCPY(umi_mt->mt_idname, mt->idname);
|
STRNCPY(umi_mt->mt_idname, mt->idname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_screen_user_menu_item_add_prop(ListBase *lb,
|
void ED_screen_user_menu_item_add_prop(bContext *C,
|
||||||
|
ListBase *lb,
|
||||||
const char *ui_name,
|
const char *ui_name,
|
||||||
const char *context_data_path,
|
const char *context_data_path,
|
||||||
const char *prop_id,
|
const char *prop_id,
|
||||||
@@ -194,6 +221,39 @@ void ED_screen_user_menu_item_add_prop(ListBase *lb,
|
|||||||
STRNCPY(umi_pr->context_data_path, context_data_path);
|
STRNCPY(umi_pr->context_data_path, context_data_path);
|
||||||
STRNCPY(umi_pr->prop_id, prop_id);
|
STRNCPY(umi_pr->prop_id, prop_id);
|
||||||
umi_pr->prop_index = prop_index;
|
umi_pr->prop_index = prop_index;
|
||||||
|
|
||||||
|
/* Copy current context name into ui_name if null */
|
||||||
|
if (ui_name && ui_name[0] != '\0')
|
||||||
|
return;
|
||||||
|
char *data_path = strchr(umi_pr->context_data_path, '.');
|
||||||
|
if (data_path) {
|
||||||
|
*data_path = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerRNA ptr = CTX_data_pointer_get(C, umi_pr->context_data_path);
|
||||||
|
if (ptr.type == NULL) {
|
||||||
|
PointerRNA ctx_ptr;
|
||||||
|
RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr);
|
||||||
|
if (!RNA_path_resolve_full(&ctx_ptr, umi_pr->context_data_path, &ptr, NULL, NULL)) {
|
||||||
|
ptr.type = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data_path) {
|
||||||
|
*data_path = '.';
|
||||||
|
data_path += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr.type != NULL) {
|
||||||
|
PropertyRNA *prop = NULL;
|
||||||
|
PointerRNA prop_ptr = ptr;
|
||||||
|
if ((data_path == NULL) || RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NULL, NULL)) {
|
||||||
|
prop = RNA_struct_find_property(&prop_ptr, umi_pr->prop_id);
|
||||||
|
}
|
||||||
|
if (prop) {
|
||||||
|
const char *name = RNA_property_ui_name(prop);
|
||||||
|
BLI_strncpy(umi_pr->item.ui_name, name, FILE_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
|
void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
|
||||||
@@ -208,50 +268,63 @@ void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
|
|||||||
/** \name Menu Definition
|
/** \name Menu Definition
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void screen_user_menu_draw(const bContext *C, Menu *menu)
|
static void screen_user_menu_draw_submenu(bContext *C, uiLayout *layout, void *arg)
|
||||||
|
{
|
||||||
|
ListBase *lb = (ListBase *)arg;
|
||||||
|
|
||||||
|
screen_user_menu_draw_items(C, layout, lb, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool screen_user_menu_draw_items(const bContext *C, uiLayout *layout, ListBase *lb, char type)
|
||||||
{
|
{
|
||||||
/* Enable when we have the ability to edit menus. */
|
/* Enable when we have the ability to edit menus. */
|
||||||
const bool show_missing = false;
|
|
||||||
char label[512];
|
char label[512];
|
||||||
|
const bool show_missing = type;
|
||||||
uint um_array_len;
|
|
||||||
bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len);
|
|
||||||
bool is_empty = true;
|
bool is_empty = true;
|
||||||
for (int um_index = 0; um_index < um_array_len; um_index++) {
|
|
||||||
bUserMenu *um = um_array[um_index];
|
int i = 0;
|
||||||
if (um == NULL) {
|
|
||||||
continue;
|
LISTBASE_FOREACH (bUserMenuItem *, umi, lb) {
|
||||||
}
|
if (type == 1 && i > 7)
|
||||||
LISTBASE_FOREACH (bUserMenuItem *, umi, &um->items) {
|
return is_empty;
|
||||||
const char *ui_name = umi->ui_name[0] ? umi->ui_name : NULL;
|
const char *ui_name = umi->ui_name[0] ? umi->ui_name : NULL;
|
||||||
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
if (umi->type == USER_MENU_TYPE_OPERATOR) {
|
||||||
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
|
||||||
wmOperatorType *ot = WM_operatortype_find(umi_op->op_idname, false);
|
wmOperatorType *ot = WM_operatortype_find(umi_op->op_idname, false);
|
||||||
if (ot != NULL) {
|
if (ot != NULL) {
|
||||||
IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
|
IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
|
||||||
uiItemFullO_ptr(menu->layout, ot, ui_name, ICON_NONE, prop, umi_op->opcontext, 0, NULL);
|
uiItemFullO_ptr(layout, ot, ui_name, umi->icon, prop, umi_op->opcontext, 0, NULL);
|
||||||
is_empty = false;
|
is_empty = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (show_missing) {
|
if (show_missing) {
|
||||||
SNPRINTF(label, "Missing: %s", umi_op->op_idname);
|
SNPRINTF(label, "Missing: %s", umi_op->op_idname);
|
||||||
uiItemL(menu->layout, label, ICON_NONE);
|
uiItemL(layout, label, ICON_NONE);
|
||||||
}
|
}
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (umi->type == USER_MENU_TYPE_MENU) {
|
else if (umi->type == USER_MENU_TYPE_MENU) {
|
||||||
bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
|
bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
|
||||||
MenuType *mt = WM_menutype_find(umi_mt->mt_idname, false);
|
MenuType *mt = WM_menutype_find(umi_mt->mt_idname, false);
|
||||||
if (mt != NULL) {
|
if (mt != NULL) {
|
||||||
uiItemM_ptr(menu->layout, mt, ui_name, ICON_NONE);
|
uiItemM_ptr(layout, mt, ui_name, umi->icon);
|
||||||
is_empty = false;
|
is_empty = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (show_missing) {
|
if (show_missing) {
|
||||||
SNPRINTF(label, "Missing: %s", umi_mt->mt_idname);
|
SNPRINTF(label, "Missing: %s", umi_mt->mt_idname);
|
||||||
uiItemL(menu->layout, label, ICON_NONE);
|
uiItemL(layout, label, ICON_NONE);
|
||||||
|
}
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (umi->type == USER_MENU_TYPE_SUBMENU) {
|
||||||
|
bUserMenuItem_SubMenu *umi_mt = (bUserMenuItem_SubMenu *)umi;
|
||||||
|
|
||||||
|
uiItemMenuF(
|
||||||
|
layout, ui_name, umi->icon, &screen_user_menu_draw_submenu, (void *)&umi_mt->items);
|
||||||
|
is_empty = false;
|
||||||
}
|
}
|
||||||
else if (umi->type == USER_MENU_TYPE_PROP) {
|
else if (umi->type == USER_MENU_TYPE_PROP) {
|
||||||
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
|
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
|
||||||
@@ -277,13 +350,11 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu)
|
|||||||
if (ptr.type != NULL) {
|
if (ptr.type != NULL) {
|
||||||
PropertyRNA *prop = NULL;
|
PropertyRNA *prop = NULL;
|
||||||
PointerRNA prop_ptr = ptr;
|
PointerRNA prop_ptr = ptr;
|
||||||
if ((data_path == NULL) ||
|
if ((data_path == NULL) || RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NULL, NULL)) {
|
||||||
RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NULL, NULL)) {
|
|
||||||
prop = RNA_struct_find_property(&prop_ptr, umi_pr->prop_id);
|
prop = RNA_struct_find_property(&prop_ptr, umi_pr->prop_id);
|
||||||
if (prop) {
|
if (prop) {
|
||||||
ok = true;
|
ok = true;
|
||||||
uiItemFullR(
|
uiItemFullR(layout, &prop_ptr, prop, umi_pr->prop_index, 0, 0, ui_name, umi->icon);
|
||||||
menu->layout, &prop_ptr, prop, umi_pr->prop_index, 0, 0, ui_name, ICON_NONE);
|
|
||||||
is_empty = false;
|
is_empty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,14 +362,52 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu)
|
|||||||
if (!ok) {
|
if (!ok) {
|
||||||
if (show_missing) {
|
if (show_missing) {
|
||||||
SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id);
|
SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id);
|
||||||
uiItemL(menu->layout, label, ICON_NONE);
|
uiItemL(layout, label, ICON_NONE);
|
||||||
}
|
}
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (umi->type == USER_MENU_TYPE_SEP) {
|
else if (umi->type == USER_MENU_TYPE_SEP) {
|
||||||
uiItemS(menu->layout);
|
uiItemS(layout);
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
return is_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_user_menu_draw_begin(bContext *C, uiLayout *layout, char type, bUserMenusGroup *umg)
|
||||||
|
{
|
||||||
|
uint um_array_len;
|
||||||
|
bUserMenu **um_array = ED_screen_user_menus_find_menu(C, &um_array_len, umg);
|
||||||
|
bool is_empty = true;
|
||||||
|
for (int um_index = 0; um_index < um_array_len; um_index++) {
|
||||||
|
bUserMenu *um = um_array[um_index];
|
||||||
|
if (um == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
is_empty = screen_user_menu_draw_items(C, layout, &um->items, true) && is_empty;
|
||||||
|
}
|
||||||
|
if (um_array) {
|
||||||
|
MEM_freeN(um_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_empty && type == 0) {
|
||||||
|
uiItemL(layout, TIP_("No menu items found"), ICON_NONE);
|
||||||
|
uiItemL(layout, TIP_("Right click on buttons to add them to this menu"), ICON_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void screen_user_menu_draw(const bContext *C, Menu *menu)
|
||||||
|
{
|
||||||
|
uint um_array_len;
|
||||||
|
bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len, 0);
|
||||||
|
bool is_empty = true;
|
||||||
|
for (int um_index = 0; um_index < um_array_len; um_index++) {
|
||||||
|
bUserMenu *um = um_array[um_index];
|
||||||
|
if (um == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
is_empty = is_empty || screen_user_menu_draw_items(C, menu->layout, &um->items, true);
|
||||||
}
|
}
|
||||||
if (um_array) {
|
if (um_array) {
|
||||||
MEM_freeN(um_array);
|
MEM_freeN(um_array);
|
||||||
|
@@ -136,6 +136,7 @@ static void userpref_main_region_layout(const bContext *C, ARegion *region)
|
|||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
const char *id = items[i].identifier;
|
const char *id = items[i].identifier;
|
||||||
|
|
||||||
BLI_assert(strlen(id) < sizeof(id_lower));
|
BLI_assert(strlen(id) < sizeof(id_lower));
|
||||||
STRNCPY(id_lower, id);
|
STRNCPY(id_lower, id);
|
||||||
BLI_str_tolower_ascii(id_lower, strlen(id_lower));
|
BLI_str_tolower_ascii(id_lower, strlen(id_lower));
|
||||||
|
@@ -515,27 +515,42 @@ typedef struct bPathCompare {
|
|||||||
char _pad0[7];
|
char _pad0[7];
|
||||||
} bPathCompare;
|
} bPathCompare;
|
||||||
|
|
||||||
|
typedef struct bUserMenusGroup {
|
||||||
|
struct bUserMenusGroup *next, *prev;
|
||||||
|
/* bUserMenu */
|
||||||
|
char idname[64];
|
||||||
|
char name[64];
|
||||||
|
char type;
|
||||||
|
char _pad0[7];
|
||||||
|
struct ListBase menus;
|
||||||
|
} bUserMenusGroup;
|
||||||
|
|
||||||
typedef struct bUserMenu {
|
typedef struct bUserMenu {
|
||||||
struct bUserMenu *next, *prev;
|
struct bUserMenu *next, *prev;
|
||||||
char space_type;
|
char space_type;
|
||||||
char _pad0[7];
|
char _pad0[7];
|
||||||
char context[64];
|
char context[64];
|
||||||
/* bUserMenuItem */
|
/* bUserMenuItem */
|
||||||
ListBase items;
|
struct ListBase items;
|
||||||
} bUserMenu;
|
} bUserMenu;
|
||||||
|
|
||||||
/** May be part of #bUserMenu or other list. */
|
/** May be part of #bUserMenu or other list. */
|
||||||
typedef struct bUserMenuItem {
|
typedef struct bUserMenuItem {
|
||||||
struct bUserMenuItem *next, *prev;
|
struct bUserMenuItem *next, *prev;
|
||||||
|
struct bUserMenuItem_SubMenu *parent;
|
||||||
|
int icon;
|
||||||
char ui_name[64];
|
char ui_name[64];
|
||||||
char type;
|
char type;
|
||||||
char _pad0[7];
|
// editor
|
||||||
|
char is_selected;
|
||||||
|
char _pad0[2];
|
||||||
} bUserMenuItem;
|
} bUserMenuItem;
|
||||||
|
|
||||||
typedef struct bUserMenuItem_Op {
|
typedef struct bUserMenuItem_Op {
|
||||||
bUserMenuItem item;
|
bUserMenuItem item;
|
||||||
char op_idname[64];
|
char op_idname[64];
|
||||||
struct IDProperty *prop;
|
struct IDProperty *prop;
|
||||||
|
struct PointerRNA *ptr;
|
||||||
char opcontext;
|
char opcontext;
|
||||||
char _pad0[7];
|
char _pad0[7];
|
||||||
} bUserMenuItem_Op;
|
} bUserMenuItem_Op;
|
||||||
@@ -545,6 +560,12 @@ typedef struct bUserMenuItem_Menu {
|
|||||||
char mt_idname[64];
|
char mt_idname[64];
|
||||||
} bUserMenuItem_Menu;
|
} bUserMenuItem_Menu;
|
||||||
|
|
||||||
|
typedef struct bUserMenuItem_SubMenu {
|
||||||
|
bUserMenuItem item;
|
||||||
|
struct ListBase items;
|
||||||
|
char name[64];
|
||||||
|
} bUserMenuItem_SubMenu;
|
||||||
|
|
||||||
typedef struct bUserMenuItem_Prop {
|
typedef struct bUserMenuItem_Prop {
|
||||||
bUserMenuItem item;
|
bUserMenuItem item;
|
||||||
char context_data_path[256];
|
char context_data_path[256];
|
||||||
@@ -558,6 +579,7 @@ enum {
|
|||||||
USER_MENU_TYPE_OPERATOR = 2,
|
USER_MENU_TYPE_OPERATOR = 2,
|
||||||
USER_MENU_TYPE_MENU = 3,
|
USER_MENU_TYPE_MENU = 3,
|
||||||
USER_MENU_TYPE_PROP = 4,
|
USER_MENU_TYPE_PROP = 4,
|
||||||
|
USER_MENU_TYPE_SUBMENU = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SolidLight {
|
typedef struct SolidLight {
|
||||||
@@ -582,7 +604,14 @@ typedef struct WalkNavigation {
|
|||||||
|
|
||||||
typedef struct UserDef_Runtime {
|
typedef struct UserDef_Runtime {
|
||||||
char is_dirty;
|
char is_dirty;
|
||||||
char _pad0[7];
|
|
||||||
|
/* User menu editor runtime datas */
|
||||||
|
char um_space_select;
|
||||||
|
char um_context_select;
|
||||||
|
char um_expanded;
|
||||||
|
char _pad0[4];
|
||||||
|
struct bUserMenuItem *um_item_select;
|
||||||
|
struct bUserMenusGroup *umg_select;
|
||||||
} UserDef_Runtime;
|
} UserDef_Runtime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -722,8 +751,10 @@ typedef struct UserDef {
|
|||||||
struct ListBase user_keyconfig_prefs;
|
struct ListBase user_keyconfig_prefs;
|
||||||
struct ListBase addons;
|
struct ListBase addons;
|
||||||
struct ListBase autoexec_paths;
|
struct ListBase autoexec_paths;
|
||||||
/** #bUserMenu. */
|
/** #bUserMenu : deprecated, keep for compatibility. */
|
||||||
struct ListBase user_menus;
|
struct ListBase user_menus;
|
||||||
|
/** #bUserMenuGroups. */
|
||||||
|
struct ListBase user_menus_group;
|
||||||
|
|
||||||
char keyconfigstr[64];
|
char keyconfigstr[64];
|
||||||
|
|
||||||
@@ -913,16 +944,17 @@ typedef enum eUserPref_Section {
|
|||||||
USER_SECTION_ADDONS = 6,
|
USER_SECTION_ADDONS = 6,
|
||||||
USER_SECTION_LIGHT = 7,
|
USER_SECTION_LIGHT = 7,
|
||||||
USER_SECTION_KEYMAP = 8,
|
USER_SECTION_KEYMAP = 8,
|
||||||
|
USER_SECTION_USER_MENUS = 9,
|
||||||
#ifdef WITH_USERDEF_WORKSPACES
|
#ifdef WITH_USERDEF_WORKSPACES
|
||||||
USER_SECTION_WORKSPACE_CONFIG = 9,
|
USER_SECTION_WORKSPACE_CONFIG = 10,
|
||||||
USER_SECTION_WORKSPACE_ADDONS = 10,
|
USER_SECTION_WORKSPACE_ADDONS = 11,
|
||||||
USER_SECTION_WORKSPACE_KEYMAPS = 11,
|
USER_SECTION_WORKSPACE_KEYMAPS = 12,
|
||||||
#endif
|
#endif
|
||||||
USER_SECTION_VIEWPORT = 12,
|
USER_SECTION_VIEWPORT = 13,
|
||||||
USER_SECTION_ANIMATION = 13,
|
USER_SECTION_ANIMATION = 14,
|
||||||
USER_SECTION_NAVIGATION = 14,
|
USER_SECTION_NAVIGATION = 15,
|
||||||
USER_SECTION_FILE_PATHS = 15,
|
USER_SECTION_FILE_PATHS = 16,
|
||||||
USER_SECTION_EXPERIMENTAL = 16,
|
USER_SECTION_EXPERIMENTAL = 17,
|
||||||
} eUserPref_Section;
|
} eUserPref_Section;
|
||||||
|
|
||||||
/** #UserDef_SpaceData.flag (State of the user preferences UI). */
|
/** #UserDef_SpaceData.flag (State of the user preferences UI). */
|
||||||
|
@@ -474,6 +474,7 @@ extern StructRNA RNA_PreferencesEdit;
|
|||||||
extern StructRNA RNA_PreferencesFilePaths;
|
extern StructRNA RNA_PreferencesFilePaths;
|
||||||
extern StructRNA RNA_PreferencesInput;
|
extern StructRNA RNA_PreferencesInput;
|
||||||
extern StructRNA RNA_PreferencesKeymap;
|
extern StructRNA RNA_PreferencesKeymap;
|
||||||
|
extern StructRNA RNA_PreferencesUserMenus;
|
||||||
extern StructRNA RNA_PreferencesSystem;
|
extern StructRNA RNA_PreferencesSystem;
|
||||||
extern StructRNA RNA_PreferencesView;
|
extern StructRNA RNA_PreferencesView;
|
||||||
extern StructRNA RNA_Property;
|
extern StructRNA RNA_Property;
|
||||||
|
@@ -1639,6 +1639,12 @@ void RNA_api_ui_layout(StructRNA *srna)
|
|||||||
RNA_def_property_ui_text(parm, "Item", "");
|
RNA_def_property_ui_text(parm, "Item", "");
|
||||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
|
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
|
||||||
api_ui_item_common_text(func);
|
api_ui_item_common_text(func);
|
||||||
|
|
||||||
|
/* User menu template */
|
||||||
|
func = RNA_def_function(
|
||||||
|
srna, "template_user_menu_item_properties", "uiTemplateUserMenuItemProperties");
|
||||||
|
parm = RNA_def_pointer(func, "item", "um_item_op", "", "");
|
||||||
|
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -88,6 +88,7 @@ const EnumPropertyItem rna_enum_preference_section_items[] = {
|
|||||||
{USER_SECTION_INPUT, "INPUT", 0, "Input", ""},
|
{USER_SECTION_INPUT, "INPUT", 0, "Input", ""},
|
||||||
{USER_SECTION_NAVIGATION, "NAVIGATION", 0, "Navigation", ""},
|
{USER_SECTION_NAVIGATION, "NAVIGATION", 0, "Navigation", ""},
|
||||||
{USER_SECTION_KEYMAP, "KEYMAP", 0, "Keymap", ""},
|
{USER_SECTION_KEYMAP, "KEYMAP", 0, "Keymap", ""},
|
||||||
|
{USER_SECTION_USER_MENUS, "USER_MENUS", 0, "User Menus", ""},
|
||||||
{0, "", 0, NULL, NULL},
|
{0, "", 0, NULL, NULL},
|
||||||
{USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""},
|
{USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""},
|
||||||
{USER_SECTION_SAVE_LOAD, "SAVE_LOAD", 0, "Save & Load", ""},
|
{USER_SECTION_SAVE_LOAD, "SAVE_LOAD", 0, "Save & Load", ""},
|
||||||
@@ -177,6 +178,7 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
|
|||||||
# include "DNA_screen_types.h"
|
# include "DNA_screen_types.h"
|
||||||
|
|
||||||
# include "BKE_blender.h"
|
# include "BKE_blender.h"
|
||||||
|
# include "BKE_blender_user_menu.h"
|
||||||
# include "BKE_global.h"
|
# include "BKE_global.h"
|
||||||
# include "BKE_idprop.h"
|
# include "BKE_idprop.h"
|
||||||
# include "BKE_image.h"
|
# include "BKE_image.h"
|
||||||
@@ -186,6 +188,8 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
|
|||||||
# include "BKE_pbvh.h"
|
# include "BKE_pbvh.h"
|
||||||
# include "BKE_screen.h"
|
# include "BKE_screen.h"
|
||||||
|
|
||||||
|
# include "ED_screen.h"
|
||||||
|
|
||||||
# include "DEG_depsgraph.h"
|
# include "DEG_depsgraph.h"
|
||||||
|
|
||||||
# include "GPU_extensions.h"
|
# include "GPU_extensions.h"
|
||||||
@@ -531,6 +535,11 @@ static PointerRNA rna_UserDef_keymap_get(PointerRNA *ptr)
|
|||||||
return rna_pointer_inherit_refine(ptr, &RNA_PreferencesKeymap, ptr->data);
|
return rna_pointer_inherit_refine(ptr, &RNA_PreferencesKeymap, ptr->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PointerRNA rna_UserDef_user_menus_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
return rna_pointer_inherit_refine(ptr, &RNA_PreferencesUserMenus, ptr->data);
|
||||||
|
}
|
||||||
|
|
||||||
static PointerRNA rna_UserDef_filepaths_get(PointerRNA *ptr)
|
static PointerRNA rna_UserDef_filepaths_get(PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
return rna_pointer_inherit_refine(ptr, &RNA_PreferencesFilePaths, ptr->data);
|
return rna_pointer_inherit_refine(ptr, &RNA_PreferencesFilePaths, ptr->data);
|
||||||
@@ -1068,6 +1077,549 @@ static void rna_UserDef_studiolight_light_ambient_get(PointerRNA *ptr, float *va
|
|||||||
copy_v3_v3(values, sl->light_ambient);
|
copy_v3_v3(values, sl->light_ambient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* User Menus Functions */
|
||||||
|
|
||||||
|
static bUserMenu *rna_UserDef_usermenus_get_current(UserDef *userdef, bool ensure)
|
||||||
|
{
|
||||||
|
const char **contexts_list = CTX_data_list_mode_string();
|
||||||
|
# if 0 /* UNUSED */
|
||||||
|
ListBase *umg_list = &userdef->user_menus_group;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
bUserMenusGroup *umg = userdef->runtime.umg_select;
|
||||||
|
bUserMenu *bum = NULL;
|
||||||
|
|
||||||
|
if (!umg)
|
||||||
|
return NULL;
|
||||||
|
if (userdef->runtime.um_space_select > 0) {
|
||||||
|
if (umg->type) {
|
||||||
|
bum = BKE_blender_user_menu_find(&umg->menus,
|
||||||
|
userdef->runtime.um_space_select,
|
||||||
|
contexts_list[userdef->runtime.um_context_select]);
|
||||||
|
if (!bum) {
|
||||||
|
bum = BKE_blender_user_menu_ensure(&umg->menus,
|
||||||
|
userdef->runtime.um_space_select,
|
||||||
|
contexts_list[userdef->runtime.um_context_select]);
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
BKE_blender_user_menu_item_add(&bum->items, USER_MENU_TYPE_SEP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (ensure) {
|
||||||
|
bum = BKE_blender_user_menu_ensure(&umg->menus,
|
||||||
|
userdef->runtime.um_space_select,
|
||||||
|
contexts_list[userdef->runtime.um_context_select]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bum = BKE_blender_user_menu_find(&umg->menus,
|
||||||
|
userdef->runtime.um_space_select,
|
||||||
|
contexts_list[userdef->runtime.um_context_select]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static bUserMenuItem *rna_UserDef_usermenus_get_current_item(UserDef *userdef)
|
||||||
|
{
|
||||||
|
int id = userdef->runtime.um_item_select - 1;
|
||||||
|
if (id < 0) return NULL;
|
||||||
|
|
||||||
|
bUserMenu *bum = rna_UserDef_usermenus_get_current(userdef, false);
|
||||||
|
if (bum) {
|
||||||
|
|
||||||
|
ListBase *lb = &bum->items;
|
||||||
|
int i = 0;
|
||||||
|
for (bUserMenuItem *umi = lb->first; umi; umi = umi->next, i++) {
|
||||||
|
if (i == id)
|
||||||
|
return umi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
static bUserMenusGroup *rna_UserDef_usermenus_get_group(UserDef *userdef, const char *idname)
|
||||||
|
{
|
||||||
|
return BKE_blender_user_menus_group_find(&userdef->user_menus_group, idname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_set_group(UserDef *userdef, bUserMenusGroup *umg)
|
||||||
|
{
|
||||||
|
userdef->runtime.umg_select = umg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_add_group(UserDef *userdef)
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = BKE_blender_user_menus_group_new("new menu");
|
||||||
|
BLI_addtail(&userdef->user_menus_group, umg);
|
||||||
|
userdef->runtime.umg_select = umg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_remove_group(UserDef *userdef)
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = userdef->runtime.umg_select;
|
||||||
|
|
||||||
|
userdef->runtime.umg_select = umg->prev;
|
||||||
|
if (!userdef->runtime.umg_select) {
|
||||||
|
userdef->runtime.umg_select = umg->next;
|
||||||
|
if (!userdef->runtime.umg_select) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_remlink(&userdef->user_menus_group, umg);
|
||||||
|
BKE_blender_user_menu_free_list(&umg->menus);
|
||||||
|
MEM_freeN(umg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rna_UserDef_usermenus_has_item(UserDef *userdef)
|
||||||
|
{
|
||||||
|
bUserMenu *bum = rna_UserDef_usermenus_get_current(userdef, false);
|
||||||
|
if (!bum)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ListBase *lb = &bum->items;
|
||||||
|
bUserMenuItem *umi = lb->first;
|
||||||
|
if (!umi)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rna_UserDef_usermenus_items_length(UserDef *userdef)
|
||||||
|
{
|
||||||
|
bUserMenu *bum = rna_UserDef_usermenus_get_current(userdef, false);
|
||||||
|
if (!bum)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ListBase *lb = &bum->items;
|
||||||
|
int i = 0;
|
||||||
|
for (bUserMenuItem *umi = lb->first; umi; umi = umi->next, i++)
|
||||||
|
;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rna_UserDef_usermenus_spacetypes_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
UserDef *userdef = (UserDef *)ptr->data;
|
||||||
|
int id = userdef->runtime.um_space_select;
|
||||||
|
id = (id <= 0) ? USER_SECTION_EDITING : id;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_active_item_set(PointerRNA *ptr, bool value)
|
||||||
|
{
|
||||||
|
bUserMenuItem *umi = (bUserMenuItem *)ptr->data;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
U.runtime.um_item_select = umi;
|
||||||
|
}
|
||||||
|
umi->is_selected = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EnumPropertyItem *rna_UserDef_usermenus_spacetypes_itemf(bContext *UNUSED(C),
|
||||||
|
PointerRNA *UNUSED(ptr),
|
||||||
|
PropertyRNA *UNUSED(prop),
|
||||||
|
bool *r_free)
|
||||||
|
{
|
||||||
|
int totitem = 0;
|
||||||
|
EnumPropertyItem *item = NULL;
|
||||||
|
int i;
|
||||||
|
const ListBase *spacetypes = BKE_spacetypes_list();
|
||||||
|
|
||||||
|
SpaceType *st = NULL;
|
||||||
|
for (i = 0, st = spacetypes->first; st; st = st->next, i++) {
|
||||||
|
int id = st->spaceid;
|
||||||
|
EnumPropertyItem new_item = {id, st->name, 0, st->name, st->name};
|
||||||
|
RNA_enum_item_add(&item, &totitem, &new_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifndef NDEBUG
|
||||||
|
if (i == 0) {
|
||||||
|
EnumPropertyItem new_item = {i, "NO_SPACETYPE", 0, "No spacetype available", ""};
|
||||||
|
RNA_enum_item_add(&item, &totitem, &new_item);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
RNA_enum_item_end(&item, &totitem);
|
||||||
|
*r_free = true;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EnumPropertyItem *rna_UserDef_usermenus_contexts_itemf(bContext *UNUSED(C),
|
||||||
|
PointerRNA *UNUSED(ptr),
|
||||||
|
PropertyRNA *UNUSED(prop),
|
||||||
|
bool *r_free)
|
||||||
|
{
|
||||||
|
static const char *contexts_list[] = {
|
||||||
|
"mesh edit", "curve edit", "surface edit", "text edit",
|
||||||
|
"armature edit", "mball edit", "lattice edit", "pose mode",
|
||||||
|
"sculpt mode", "weight paint", "vertex paint", "image paint",
|
||||||
|
"particle mode", "object mode", "greasepencil paint", "greasepencil edit",
|
||||||
|
"greasepencil sculpt", "greasepencil weight", "greasepencil vertex", NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
int totitem = 0;
|
||||||
|
EnumPropertyItem *item = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; contexts_list[i]; i++) {
|
||||||
|
EnumPropertyItem new_item = {i, contexts_list[i], 0, contexts_list[i], contexts_list[i]};
|
||||||
|
RNA_enum_item_add(&item, &totitem, &new_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifndef NDEBUG
|
||||||
|
if (i == 0) {
|
||||||
|
EnumPropertyItem new_item = {i, "NO_CONTEXT", 0, "No context available", ""};
|
||||||
|
RNA_enum_item_add(&item, &totitem, &new_item);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
RNA_enum_item_end(&item, &totitem);
|
||||||
|
*r_free = true;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EnumPropertyItem *rna_UserDef_icons_itemf(bContext *UNUSED(C),
|
||||||
|
PointerRNA *UNUSED(ptr),
|
||||||
|
PropertyRNA *UNUSED(prop),
|
||||||
|
bool *r_free)
|
||||||
|
{
|
||||||
|
int totitem = 0;
|
||||||
|
const EnumPropertyItem *list = rna_enum_icon_items;
|
||||||
|
EnumPropertyItem *item = NULL;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; list[i].identifier; i++) {
|
||||||
|
EnumPropertyItem new_item = {
|
||||||
|
list[i].value, list[i].identifier, list[i].value, list[i].name, list[i].description};
|
||||||
|
RNA_enum_item_add(&item, &totitem, &new_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifndef NDEBUG
|
||||||
|
if (i == 0) {
|
||||||
|
EnumPropertyItem new_item = {i, "NONE", 0, "No icons", ""};
|
||||||
|
RNA_enum_item_add(&item, &totitem, &new_item);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
RNA_enum_item_end(&item, &totitem);
|
||||||
|
*r_free = true;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_item_add(UserDef *userdef, int index)
|
||||||
|
{
|
||||||
|
bUserMenu *um = rna_UserDef_usermenus_get_current(userdef, true);
|
||||||
|
if (!um)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ListBase *lb = &um->items;
|
||||||
|
bUserMenuItem_Op *umi = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(
|
||||||
|
NULL, USER_MENU_TYPE_OPERATOR);
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
BLI_addtail(lb, umi);
|
||||||
|
else {
|
||||||
|
int i = 0;
|
||||||
|
for (bUserMenuItem *insert = lb->first; insert; insert = insert->next, i++) {
|
||||||
|
if (i == index) {
|
||||||
|
BLI_insertlinkbefore(lb, insert, umi);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLI_addtail(lb, umi);
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic operator setup
|
||||||
|
wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_add", true);
|
||||||
|
STRNCPY(umi->item.ui_name, "new item");
|
||||||
|
STRNCPY(umi->op_idname, ot->idname);
|
||||||
|
userdef->runtime.um_item_select = &umi->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_item_remove(UserDef *userdef)
|
||||||
|
{
|
||||||
|
bUserMenu *bum = rna_UserDef_usermenus_get_current(userdef, true);
|
||||||
|
bUserMenuItem *umi = userdef->runtime.um_item_select;
|
||||||
|
if (!bum || !umi)
|
||||||
|
return;
|
||||||
|
|
||||||
|
userdef->runtime.um_item_select = umi->next;
|
||||||
|
if (!userdef->runtime.um_item_select)
|
||||||
|
userdef->runtime.um_item_select = umi->prev;
|
||||||
|
ListBase *lb = (umi->parent) ? &umi->parent->items : &bum->items;
|
||||||
|
ED_screen_user_menu_item_remove(lb, umi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_item_move(UserDef *userdef, bool up)
|
||||||
|
{
|
||||||
|
bUserMenu *bum = rna_UserDef_usermenus_get_current(userdef, true);
|
||||||
|
bUserMenuItem *umi = userdef->runtime.um_item_select;
|
||||||
|
if (!bum || !umi)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ListBase *lb = (umi->parent) ? &umi->parent->items : &bum->items;
|
||||||
|
bUserMenuItem *umi_toward = (up) ? umi->prev : umi->next;
|
||||||
|
BLI_remlink(lb, umi);
|
||||||
|
|
||||||
|
if (!umi_toward) {
|
||||||
|
|
||||||
|
if (!umi->parent)
|
||||||
|
return;
|
||||||
|
if (!umi->parent->item.parent) {
|
||||||
|
if (up)
|
||||||
|
BLI_insertlinkbefore(&bum->items, umi->parent, umi);
|
||||||
|
else
|
||||||
|
BLI_insertlinkafter(&bum->items, umi->parent, umi);
|
||||||
|
umi->parent = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (up)
|
||||||
|
BLI_insertlinkbefore(&umi->parent->item.parent->items, umi->parent, umi);
|
||||||
|
else
|
||||||
|
BLI_insertlinkafter(&umi->parent->item.parent->items, umi->parent, umi);
|
||||||
|
umi->parent = umi->parent->item.parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (umi_toward->type == USER_MENU_TYPE_SUBMENU) {
|
||||||
|
bUserMenuItem_SubMenu *umi_sm = (bUserMenuItem_SubMenu *)umi_toward;
|
||||||
|
if (up)
|
||||||
|
BLI_addtail(&umi_sm->items, umi);
|
||||||
|
else
|
||||||
|
BLI_addhead(&umi_sm->items, umi);
|
||||||
|
umi->parent = umi_sm;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (up)
|
||||||
|
BLI_insertlinkbefore(lb, umi->prev, umi);
|
||||||
|
else
|
||||||
|
BLI_insertlinkafter(lb, umi->next, umi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_pie_item_add(UserDef *userdef, int index)
|
||||||
|
{
|
||||||
|
bUserMenu *um = rna_UserDef_usermenus_get_current(userdef, true);
|
||||||
|
if (!um)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bUserMenuItem_Op *umi = NULL;
|
||||||
|
ListBase *lb = &um->items;
|
||||||
|
bUserMenuItem *insert = lb->first;
|
||||||
|
int i = 0;
|
||||||
|
for (insert = lb->first; insert; insert = insert->next, i++) {
|
||||||
|
if (insert->type != USER_MENU_TYPE_SUBMENU)
|
||||||
|
continue;
|
||||||
|
bUserMenuItem_SubMenu *sm = (bUserMenuItem_SubMenu *)insert;
|
||||||
|
if (i == index) {
|
||||||
|
umi = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(&sm->items,
|
||||||
|
USER_MENU_TYPE_OPERATOR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!umi)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// basic operator setup
|
||||||
|
wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_add", true);
|
||||||
|
STRNCPY(umi->item.ui_name, "new item");
|
||||||
|
STRNCPY(umi->op_idname, ot->idname);
|
||||||
|
umi->item.parent = (bUserMenuItem_SubMenu *)insert;
|
||||||
|
userdef->runtime.um_item_select = &umi->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_item_type_set(PointerRNA *ptr, int value)
|
||||||
|
{
|
||||||
|
bUserMenuItem *umi = (bUserMenuItem *)ptr->data;
|
||||||
|
bUserMenu *bum = rna_UserDef_usermenus_get_current(&U, true);
|
||||||
|
|
||||||
|
if (!bum || !umi || umi->type == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ListBase *lb = (!umi->parent) ? &bum->items : &umi->parent->items;
|
||||||
|
BLI_remlink(lb, umi);
|
||||||
|
bUserMenuItem *new_umi = BKE_blender_user_menu_item_add(NULL, value);
|
||||||
|
new_umi->parent = umi->parent;
|
||||||
|
if (value == USER_MENU_TYPE_SUBMENU) {
|
||||||
|
bUserMenuItem_SubMenu *umi_sm = (bUserMenuItem_SubMenu *)new_umi;
|
||||||
|
BLI_listbase_clear(&umi_sm->items);
|
||||||
|
}
|
||||||
|
BLI_insertlinkafter(lb, umi->prev, new_umi);
|
||||||
|
STRNCPY(new_umi->ui_name, umi->ui_name);
|
||||||
|
BKE_blender_user_menu_item_free(umi);
|
||||||
|
U.runtime.um_item_select = new_umi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rna_UserDef_usermenus_item_type_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
bUserMenuItem *data = (bUserMenuItem *)(ptr->data);
|
||||||
|
if (data)
|
||||||
|
return (int)(data->type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_item_name_get(PointerRNA *ptr, char *value)
|
||||||
|
{
|
||||||
|
bUserMenuItem *umi = (bUserMenuItem *)(ptr->data);
|
||||||
|
|
||||||
|
if (!*umi->ui_name) {
|
||||||
|
const char *name = " ";
|
||||||
|
if (umi->type == USER_MENU_TYPE_MENU) {
|
||||||
|
bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
|
||||||
|
MenuType *mt = WM_menutype_find(umi_mt->mt_idname, true);
|
||||||
|
name = (const char *)CTX_IFACE_(mt->translation_context, mt->label);
|
||||||
|
BLI_strncpy(umi->ui_name, name, FILE_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLI_strncpy(value, umi->ui_name, FILE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_pie_set(PointerRNA *ptr, int value)
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = (bUserMenusGroup *)ptr->data;
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (bUserMenu *, um, &umg->menus) {
|
||||||
|
ListBase *lb = &um->items;
|
||||||
|
BKE_blender_user_menu_item_free_list(lb);
|
||||||
|
if (value)
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_SEP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
umg->type = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PointerRNA rna_UserDef_usermenus_item_op_prop_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
bUserMenuItem_Op *umi_op = ptr->data;
|
||||||
|
|
||||||
|
if (umi_op->ptr) {
|
||||||
|
return *(umi_op->ptr);
|
||||||
|
}
|
||||||
|
return PointerRNA_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_group_idname_set(Main *bmain,
|
||||||
|
Scene *UNUSED(scene),
|
||||||
|
PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
bUserMenusGroup *umg = (bUserMenusGroup *)ptr->data;
|
||||||
|
# if 0
|
||||||
|
const char *name = umg->name;
|
||||||
|
# endif
|
||||||
|
char old[64] = {'\0'};
|
||||||
|
|
||||||
|
STRNCPY(old, umg->idname);
|
||||||
|
BKE_blender_user_menus_group_idname_update(umg);
|
||||||
|
BKE_blender_user_menus_group_idname_update_keymap(bmain->wm.first, old, umg->idname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_item_op_get(PointerRNA *ptr, char *value)
|
||||||
|
{
|
||||||
|
bUserMenuItem_Op *umi_op = ptr->data;
|
||||||
|
WM_operator_py_idname(value, umi_op->op_idname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rna_UserDef_usermenus_item_op_length(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
bUserMenuItem_Op *umi_op = ptr->data;
|
||||||
|
char pyname[OP_MAX_TYPENAME];
|
||||||
|
|
||||||
|
WM_operator_py_idname(pyname, umi_op->op_idname);
|
||||||
|
return strlen(pyname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenus_item_op_set(PointerRNA *ptr, const char *value)
|
||||||
|
{
|
||||||
|
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)ptr->data;
|
||||||
|
char idname_bl[OP_MAX_TYPENAME];
|
||||||
|
|
||||||
|
wmOperatorType *origin_ot = WM_operatortype_find(umi_op->op_idname, true);
|
||||||
|
wmOperatorType *ot = WM_operatortype_find(value, false);
|
||||||
|
if (origin_ot == ot || ot == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WM_operator_bl_idname(idname_bl, value);
|
||||||
|
WM_operator_py_idname(umi_op->op_idname, value);
|
||||||
|
|
||||||
|
if (LIKELY(umi_op->ptr)) {
|
||||||
|
WM_operator_properties_free(umi_op->ptr);
|
||||||
|
MEM_freeN(umi_op->ptr);
|
||||||
|
|
||||||
|
umi_op->ptr = NULL;
|
||||||
|
}
|
||||||
|
umi_op->prop = NULL;
|
||||||
|
|
||||||
|
WM_operator_properties_alloc(&(umi_op->ptr), &(umi_op->prop), idname_bl);
|
||||||
|
WM_operator_properties_sanitize(umi_op->ptr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenu_draw(UserDef *UNUSED(userdef),
|
||||||
|
bContext *C,
|
||||||
|
uiLayout *layout,
|
||||||
|
bUserMenusGroup *umg)
|
||||||
|
{
|
||||||
|
screen_user_menu_draw_begin(C, layout, true, umg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UserMenu.menu_items */
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenu_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
bUserMenu *bum = (bUserMenu *)ptr->data;
|
||||||
|
rna_iterator_listbase_begin(iter, &bum->items, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenu_submenu_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
bUserMenuItem_SubMenu *umi_sm = (bUserMenuItem_SubMenu *)ptr->data;
|
||||||
|
rna_iterator_listbase_begin(iter, &umi_sm->items, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bUserMenuItem_Op *rna_UserDef_usermenus_item_operator_get(bUserMenuItem *umi)
|
||||||
|
{
|
||||||
|
if (umi->type == USER_MENU_TYPE_OPERATOR)
|
||||||
|
return (bUserMenuItem_Op *)umi;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bUserMenuItem_Menu *rna_UserDef_usermenus_item_menu_get(bUserMenuItem *umi)
|
||||||
|
{
|
||||||
|
if (umi->type == USER_MENU_TYPE_MENU)
|
||||||
|
return (bUserMenuItem_Menu *)umi;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bUserMenuItem_Prop *rna_UserDef_usermenus_item_property_get(bUserMenuItem *umi)
|
||||||
|
{
|
||||||
|
if (umi->type == USER_MENU_TYPE_PROP)
|
||||||
|
return (bUserMenuItem_Prop *)umi;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bUserMenuItem_SubMenu *rna_UserDef_usermenus_item_submenu_get(bUserMenuItem *umi)
|
||||||
|
{
|
||||||
|
if (umi->type == USER_MENU_TYPE_SUBMENU)
|
||||||
|
return (bUserMenuItem_SubMenu *)umi;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UserMenus.menus */
|
||||||
|
|
||||||
|
static void rna_UserDef_usermenu_menus_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
UserDef *userdef = (UserDef *)ptr->data;
|
||||||
|
rna_iterator_listbase_begin(iter, &userdef->user_menus_group, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int rna_show_statusbar_vram_editable(struct PointerRNA *UNUSED(ptr), const char **UNUSED(r_info))
|
int rna_show_statusbar_vram_editable(struct PointerRNA *UNUSED(ptr), const char **UNUSED(r_info))
|
||||||
{
|
{
|
||||||
return GPU_mem_stats_supported() ? PROP_EDITABLE : 0;
|
return GPU_mem_stats_supported() ? PROP_EDITABLE : 0;
|
||||||
@@ -5910,6 +6462,384 @@ static void rna_def_userdef_keymap(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Key Config", "The name of the active key configuration");
|
RNA_def_property_ui_text(prop, "Key Config", "The name of the active key configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rna_def_userdef_usermenus_items_subtypes(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
/* operator item */
|
||||||
|
srna = RNA_def_struct(brna, "um_item_op", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "bUserMenuItem_Op");
|
||||||
|
RNA_def_struct_ui_text(
|
||||||
|
srna, "User Menu operator item", "an item of the user menus that can store an operator");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "item", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "item");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "operator", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "op_idname");
|
||||||
|
RNA_def_property_ui_text(prop, "operator", "the operator that will be executed");
|
||||||
|
RNA_def_property_string_funcs(prop,
|
||||||
|
"rna_UserDef_usermenus_item_op_get",
|
||||||
|
"rna_UserDef_usermenus_item_op_length",
|
||||||
|
"rna_UserDef_usermenus_item_op_set");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "prop", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "prop");
|
||||||
|
RNA_def_property_struct_type(prop, "OperatorProperties");
|
||||||
|
RNA_def_property_ui_text(prop, "properties", "properties of the operator");
|
||||||
|
RNA_def_property_pointer_funcs(prop, "rna_UserDef_usermenus_item_op_prop_get", NULL, NULL, NULL);
|
||||||
|
|
||||||
|
/* menu item */
|
||||||
|
srna = RNA_def_struct(brna, "um_item_menu", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "bUserMenuItem_Menu");
|
||||||
|
RNA_def_struct_ui_text(
|
||||||
|
srna, "User Menu menu item", "an item of the user menus that can store a submenu");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "item", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "item");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "id_name", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "mt_idname");
|
||||||
|
RNA_def_property_ui_text(prop, "id name", "the menu id name");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
/* prop item */
|
||||||
|
srna = RNA_def_struct(brna, "um_item_prop", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "bUserMenuItem_Prop");
|
||||||
|
RNA_def_struct_ui_text(
|
||||||
|
srna, "User Menu property item", "an item of the user menus that can store a property");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "item", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "item");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "id_name", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "prop_id");
|
||||||
|
RNA_def_property_ui_text(prop, "id name", "the property id name");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "context", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "context_data_path");
|
||||||
|
RNA_def_property_ui_text(prop, "context", "the context data path of the property");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
/* sub menu item */
|
||||||
|
srna = RNA_def_struct(brna, "um_item_submenu", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "bUserMenuItem_SubMenu");
|
||||||
|
RNA_def_struct_ui_text(
|
||||||
|
srna, "User Menu sub menu item", "an item of the user menus that can store a sub menu");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "item", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "item");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "name");
|
||||||
|
RNA_def_property_ui_text(prop, "name", "the sub menu name");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "items_list", PROP_COLLECTION, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "sub menu items", "list of the items of the sub menu");
|
||||||
|
RNA_def_property_collection_funcs(prop,
|
||||||
|
"rna_UserDef_usermenu_submenu_begin",
|
||||||
|
"rna_iterator_listbase_next",
|
||||||
|
NULL,
|
||||||
|
"rna_iterator_listbase_get",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_def_userdef_usermenu(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
FunctionRNA *func;
|
||||||
|
PropertyRNA *parm;
|
||||||
|
|
||||||
|
/* user menu */
|
||||||
|
srna = RNA_def_struct(brna, "UserMenu", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "bUserMenu");
|
||||||
|
RNA_def_struct_ui_text(srna, "User Menu", "an user menu");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "spacetype", PROP_INT, PROP_NONE);
|
||||||
|
RNA_def_property_int_sdna(prop, NULL, "space_type");
|
||||||
|
RNA_def_property_ui_text(prop, "Space Type", "The Space type the user menu will be used in");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "context", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "context");
|
||||||
|
RNA_def_property_ui_text(prop, "Context", "The Context the user menu will be used in");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "menu_items", PROP_COLLECTION, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "Items", "list of the items of the menu");
|
||||||
|
RNA_def_property_collection_funcs(prop,
|
||||||
|
"rna_UserDef_usermenu_items_begin",
|
||||||
|
"rna_iterator_listbase_next",
|
||||||
|
NULL,
|
||||||
|
"rna_iterator_listbase_get",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* user menu item */
|
||||||
|
static const EnumPropertyItem um_item_type[] = {
|
||||||
|
{USER_MENU_TYPE_OPERATOR, "OPERATOR", 0, "Operator", "Operator"},
|
||||||
|
{USER_MENU_TYPE_PROP, "PROPERTY", 0, "Property", "Property"},
|
||||||
|
{USER_MENU_TYPE_SUBMENU, "SUBMENU", 0, "Menu", "Menu"},
|
||||||
|
{USER_MENU_TYPE_MENU, "MENU", 0, "Packed Menu", "Packed Menu"},
|
||||||
|
{USER_MENU_TYPE_SEP, "SEPARATOR", 0, "Separator", "Separator"},
|
||||||
|
{0, NULL, 0, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "UserMenuItem", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "bUserMenuItem");
|
||||||
|
RNA_def_struct_ui_text(srna, "User Menu Item", "User Menu item");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "next", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "next");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "prev", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "prev");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "parent");
|
||||||
|
RNA_def_property_struct_type(prop, "um_item_submenu");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "ui_name");
|
||||||
|
RNA_def_property_string_funcs(prop, "rna_UserDef_usermenus_item_name_get", NULL, NULL);
|
||||||
|
RNA_def_property_ui_text(prop, "Name", "Name of the item");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "type");
|
||||||
|
RNA_def_property_enum_items(prop, um_item_type);
|
||||||
|
RNA_def_property_enum_funcs(
|
||||||
|
prop, "rna_UserDef_usermenus_item_type_get", "rna_UserDef_usermenus_item_type_set", NULL);
|
||||||
|
RNA_def_property_ui_text(prop, "type", "the type of item");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "icon");
|
||||||
|
RNA_def_property_enum_items(prop, rna_enum_icon_items);
|
||||||
|
RNA_def_property_enum_default(prop, ICON_NONE);
|
||||||
|
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_UserDef_icons_itemf");
|
||||||
|
RNA_def_property_ui_text(prop, "Icon", "The item icon");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "is_selected", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "is_selected", 0);
|
||||||
|
RNA_def_property_ui_text(prop, "is selected", "is selected");
|
||||||
|
RNA_def_property_boolean_funcs(prop, NULL, "rna_UserDef_usermenus_active_item_set");
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "get_operator", "rna_UserDef_usermenus_item_operator_get");
|
||||||
|
RNA_def_function_ui_description(func, "return the operator item");
|
||||||
|
parm = RNA_def_pointer(func, "item_op", "um_item_op", "", "the item operator");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "get_menu", "rna_UserDef_usermenus_item_menu_get");
|
||||||
|
RNA_def_function_ui_description(func, "return the operator menu");
|
||||||
|
parm = RNA_def_pointer(func, "item_menu", "um_item_menu", "", "the item menu");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "get_property", "rna_UserDef_usermenus_item_property_get");
|
||||||
|
RNA_def_function_ui_description(func, "return the operator property");
|
||||||
|
parm = RNA_def_pointer(func, "item_prop", "um_item_prop", "", "the item property");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "get_submenu", "rna_UserDef_usermenus_item_submenu_get");
|
||||||
|
RNA_def_function_ui_description(func, "return the submenu");
|
||||||
|
parm = RNA_def_pointer(func, "item_submenu", "um_item_submenu", "", "the item submenu");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
rna_def_userdef_usermenus_items_subtypes(brna);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_def_userdef_usermenusgroup(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
static const EnumPropertyItem um_menu_type[] = {
|
||||||
|
{0, "LIST", 0, "List", "List"},
|
||||||
|
{1, "PIE", 0, "Pie", "Pie"},
|
||||||
|
{0, NULL, 0, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* user menus group */
|
||||||
|
srna = RNA_def_struct(brna, "UserMenusGroup", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "bUserMenusGroup");
|
||||||
|
RNA_def_struct_ui_text(srna, "User Menus Group", "A whole displayble user menu");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "name");
|
||||||
|
RNA_def_property_ui_text(prop, "Name", "Name of the user menu group");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
RNA_def_property_update(prop, 0, "rna_UserDef_usermenus_group_idname_set");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_sdna(prop, NULL, "idname");
|
||||||
|
RNA_def_property_ui_text(prop, "ID Name", "ID Name of the user menu group");
|
||||||
|
RNA_def_struct_name_property(srna, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "type");
|
||||||
|
RNA_def_property_enum_items(prop, um_menu_type);
|
||||||
|
RNA_def_property_ui_text(prop, "menu type", "change menu type between list and pie");
|
||||||
|
RNA_def_property_enum_funcs(prop, NULL, "rna_UserDef_usermenus_pie_set", NULL);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "menus", PROP_COLLECTION, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenu");
|
||||||
|
RNA_def_property_ui_text(prop, "User Menu", "list of user sub menus contained in the group");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_def_userdef_usermenus_editor(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
PropertyRNA *prop;
|
||||||
|
FunctionRNA *func;
|
||||||
|
PropertyRNA *parm;
|
||||||
|
|
||||||
|
static const EnumPropertyItem um_space_default[] = {
|
||||||
|
{0, "NULL", 0, "None", "No spacetypes found"},
|
||||||
|
{0, NULL, 0, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const EnumPropertyItem um_context_default[] = {
|
||||||
|
{0, "NULL", 0, "None", "No context found"},
|
||||||
|
{0, NULL, 0, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
StructRNA *srna = RNA_def_struct(brna, "PreferencesUserMenus", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "UserDef");
|
||||||
|
RNA_def_struct_nested(brna, srna, "Preferences");
|
||||||
|
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
|
||||||
|
RNA_def_struct_ui_text(srna, "User Menus", "User Menus editor");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "space_selected", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "runtime.um_space_select");
|
||||||
|
RNA_def_property_enum_items(prop, um_space_default);
|
||||||
|
RNA_def_property_enum_funcs(prop,
|
||||||
|
"rna_UserDef_usermenus_spacetypes_get",
|
||||||
|
NULL,
|
||||||
|
"rna_UserDef_usermenus_spacetypes_itemf");
|
||||||
|
RNA_def_property_ui_text(prop, "space type selected", "the space type selected");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "context_selected", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "runtime.um_context_select");
|
||||||
|
RNA_def_property_enum_items(prop, um_context_default);
|
||||||
|
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_UserDef_usermenus_contexts_itemf");
|
||||||
|
RNA_def_property_ui_text(prop, "context selected", "the context selected");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "active_item", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "runtime.um_item_select");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenuItem");
|
||||||
|
RNA_def_property_ui_text(prop, "item", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "active_group", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
|
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "runtime.umg_select");
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenusGroup");
|
||||||
|
RNA_def_property_ui_text(prop, "active user menus group", "active user menus group");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "menus", PROP_COLLECTION, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "UserMenusGroup");
|
||||||
|
RNA_def_property_ui_text(prop, "Menus", "list of the menus");
|
||||||
|
RNA_def_property_collection_funcs(prop,
|
||||||
|
"rna_UserDef_usermenu_menus_begin",
|
||||||
|
"rna_iterator_listbase_next",
|
||||||
|
"rna_iterator_listbase_end",
|
||||||
|
"rna_iterator_listbase_get",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "expanded", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "runtime.um_expanded", 0);
|
||||||
|
RNA_def_property_ui_text(prop, "Items Expanded", "Expanded in the user interface");
|
||||||
|
RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
|
||||||
|
|
||||||
|
rna_def_userdef_usermenu(brna);
|
||||||
|
rna_def_userdef_usermenusgroup(brna);
|
||||||
|
|
||||||
|
// functions
|
||||||
|
func = RNA_def_function(srna, "get_current_menu", "rna_UserDef_usermenus_get_current");
|
||||||
|
RNA_def_function_ui_description(func, "get active user menu");
|
||||||
|
parm = RNA_def_boolean(func, "ensure", false, "ensure", "create the menu if don't exist");
|
||||||
|
parm = RNA_def_pointer(func, "current_menu", "UserMenu", "", "the menu");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "get_group", "rna_UserDef_usermenus_get_group");
|
||||||
|
RNA_def_function_ui_description(func, "get user menus group by idname");
|
||||||
|
parm = RNA_def_string(func, "idname", NULL, 0, "ID name", "ID name of the group");
|
||||||
|
parm = RNA_def_pointer(func, "menu", "UserMenusGroup", "", "the menu group");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "set_group", "rna_UserDef_usermenus_set_group");
|
||||||
|
RNA_def_function_ui_description(func, "set the group menu to edit");
|
||||||
|
parm = RNA_def_pointer(func, "new_group", "UserMenusGroup", "", "the group menu");
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "add_group", "rna_UserDef_usermenus_add_group");
|
||||||
|
RNA_def_function_ui_description(func, "add a group");
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "remove_group", "rna_UserDef_usermenus_remove_group");
|
||||||
|
RNA_def_function_ui_description(func, "remove a group");
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "items_len", "rna_UserDef_usermenus_items_length");
|
||||||
|
RNA_def_function_ui_description(func, "Refresh custom menu editor");
|
||||||
|
parm = RNA_def_int(func, "len", 0, 0, 1000, "", "the list len", 0, 1000);
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "has_item", "rna_UserDef_usermenus_has_item");
|
||||||
|
RNA_def_function_ui_description(func, "the current list has items");
|
||||||
|
parm = RNA_def_boolean(func, "has_item", false, "", "is there items in the current list ?");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "item_add", "rna_UserDef_usermenus_item_add");
|
||||||
|
RNA_def_function_ui_description(func, "add an item to a menu");
|
||||||
|
parm = RNA_def_int(func, "index", 0, -1, 1000, "index", "index to insert the item", -1, 1000);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "item_remove", "rna_UserDef_usermenus_item_remove");
|
||||||
|
RNA_def_function_ui_description(func, "remove an item from a user menu");
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "item_move", "rna_UserDef_usermenus_item_move");
|
||||||
|
RNA_def_function_ui_description(func, "up an item");
|
||||||
|
parm = RNA_def_boolean(func, "up", false, "", "go up ?");
|
||||||
|
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "pie_item_add", "rna_UserDef_usermenus_pie_item_add");
|
||||||
|
RNA_def_function_ui_description(func, "add an item to a menu");
|
||||||
|
parm = RNA_def_int(func, "index", 0, -1, 1000, "index", "index to insert the item", -1, 1000);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "draw_menu", "rna_UserDef_usermenu_draw");
|
||||||
|
RNA_def_function_ui_description(func, "draw items of usermenu");
|
||||||
|
parm = RNA_def_pointer(func, "context", "Context", "", "context");
|
||||||
|
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||||
|
parm = RNA_def_pointer(func, "layout", "UILayout", "", "layout");
|
||||||
|
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||||
|
parm = RNA_def_pointer(func, "menu", "UserMenusGroup", "", "menu");
|
||||||
|
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
static void rna_def_userdef_filepaths(BlenderRNA *brna)
|
static void rna_def_userdef_filepaths(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
@@ -6248,6 +7178,12 @@ void RNA_def_userdef(BlenderRNA *brna)
|
|||||||
RNA_def_property_pointer_funcs(prop, "rna_UserDef_keymap_get", NULL, NULL, NULL);
|
RNA_def_property_pointer_funcs(prop, "rna_UserDef_keymap_get", NULL, NULL, NULL);
|
||||||
RNA_def_property_ui_text(prop, "Keymap", "Shortcut setup for keyboards and other input devices");
|
RNA_def_property_ui_text(prop, "Keymap", "Shortcut setup for keyboards and other input devices");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "user_menus", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
|
RNA_def_property_struct_type(prop, "PreferencesUserMenus");
|
||||||
|
RNA_def_property_pointer_funcs(prop, "rna_UserDef_user_menus_get", NULL, NULL, NULL);
|
||||||
|
RNA_def_property_ui_text(prop, "User Menus", "User Menus Editor");
|
||||||
|
|
||||||
prop = RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NONE);
|
prop = RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
RNA_def_property_struct_type(prop, "PreferencesFilePaths");
|
RNA_def_property_struct_type(prop, "PreferencesFilePaths");
|
||||||
@@ -6315,6 +7251,7 @@ void RNA_def_userdef(BlenderRNA *brna)
|
|||||||
rna_def_userdef_edit(brna);
|
rna_def_userdef_edit(brna);
|
||||||
rna_def_userdef_input(brna);
|
rna_def_userdef_input(brna);
|
||||||
rna_def_userdef_keymap(brna);
|
rna_def_userdef_keymap(brna);
|
||||||
|
rna_def_userdef_usermenus_editor(brna);
|
||||||
rna_def_userdef_filepaths(brna);
|
rna_def_userdef_filepaths(brna);
|
||||||
rna_def_userdef_system(brna);
|
rna_def_userdef_system(brna);
|
||||||
rna_def_userdef_addon(brna);
|
rna_def_userdef_addon(brna);
|
||||||
|
@@ -1841,6 +1841,8 @@ static void rna_struct_update_when_changed(bContext *C,
|
|||||||
PointerRNA *ptr_b)
|
PointerRNA *ptr_b)
|
||||||
{
|
{
|
||||||
CollectionPropertyIterator iter;
|
CollectionPropertyIterator iter;
|
||||||
|
if (!ptr_a->data || !ptr_b->data)
|
||||||
|
return;
|
||||||
PropertyRNA *iterprop = RNA_struct_iterator_property(ptr_a->type);
|
PropertyRNA *iterprop = RNA_struct_iterator_property(ptr_a->type);
|
||||||
BLI_assert(ptr_a->type == ptr_b->type);
|
BLI_assert(ptr_a->type == ptr_b->type);
|
||||||
RNA_property_collection_begin(ptr_a, iterprop, &iter);
|
RNA_property_collection_begin(ptr_a, iterprop, &iter);
|
||||||
|
Submodule source/tools updated: 896c5f7895...6034199b44
Reference in New Issue
Block a user