forked from bartvdbraak/blender
user-preferences for addons. currently unused, example & docs still to come.
This commit is contained in:
parent
18f134304c
commit
79c2571e56
@ -1162,7 +1162,8 @@ class USERPREF_PT_addons(Panel):
|
||||
continue
|
||||
|
||||
# Addon UI Code
|
||||
box = col.column().box()
|
||||
col_box = col.column()
|
||||
box = col_box.box()
|
||||
colsub = box.column()
|
||||
row = colsub.row()
|
||||
|
||||
@ -1225,6 +1226,25 @@ class USERPREF_PT_addons(Panel):
|
||||
for i in range(4 - tot_row):
|
||||
split.separator()
|
||||
|
||||
# Show addon user preferences
|
||||
if is_enabled:
|
||||
addon_preferences = userpref.addons[module_name].preferences
|
||||
if addon_preferences is not None:
|
||||
draw = getattr(addon_preferences, "draw", None)
|
||||
if draw is not None:
|
||||
addon_preferences_class = type(addon_preferences)
|
||||
box_prefs = col_box.box()
|
||||
box_prefs.label("Preferences:")
|
||||
addon_preferences_class.layout = box_prefs
|
||||
try:
|
||||
draw(context)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
box_prefs.label(text="Error (see console)", icon='ERROR')
|
||||
del addon_preferences_class.layout
|
||||
|
||||
|
||||
# Append missing scripts
|
||||
# First collect scripts that are used but have no script file.
|
||||
module_names = {mod.__name__ for mod, info in addons}
|
||||
|
42
source/blender/blenkernel/BKE_addon.h
Normal file
42
source/blender/blenkernel/BKE_addon.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* Contributor(s): Campbell Barton
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BKE_ADDON_H__
|
||||
#define __BKE_ADDON_H__
|
||||
|
||||
#include "RNA_types.h"
|
||||
|
||||
typedef struct bAddonPrefType {
|
||||
/* type info */
|
||||
char idname[64]; // best keep the same size as BKE_ST_MAXNAME
|
||||
|
||||
/* RNA integration */
|
||||
ExtensionRNA ext;
|
||||
} bAddonPrefType;
|
||||
|
||||
bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet);
|
||||
void BKE_addon_pref_type_add(bAddonPrefType *apt);
|
||||
void BKE_addon_pref_type_remove(bAddonPrefType *apt);
|
||||
|
||||
void BKE_addon_pref_type_init(void);
|
||||
void BKE_addon_pref_type_free(void);
|
||||
|
||||
#endif /* __BKE_ADDON_H__ */
|
@ -58,6 +58,7 @@ set(SRC
|
||||
intern/CCGSubSurf.c
|
||||
intern/DerivedMesh.c
|
||||
intern/action.c
|
||||
intern/addon.c
|
||||
intern/anim.c
|
||||
intern/anim_sys.c
|
||||
intern/armature.c
|
||||
@ -152,6 +153,7 @@ set(SRC
|
||||
|
||||
BKE_DerivedMesh.h
|
||||
BKE_action.h
|
||||
BKE_addon.h
|
||||
BKE_anim.h
|
||||
BKE_animsys.h
|
||||
BKE_armature.h
|
||||
|
84
source/blender/blenkernel/intern/addon.c
Normal file
84
source/blender/blenkernel/intern/addon.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* Contributor(s): Campbell Barton
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_addon.h" /* own include */
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "BLF_translation.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
static GHash *global_addonpreftype_hash = NULL;
|
||||
|
||||
|
||||
bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet)
|
||||
{
|
||||
if (idname[0]) {
|
||||
bAddonPrefType *apt;
|
||||
|
||||
apt = BLI_ghash_lookup(global_addonpreftype_hash, idname);
|
||||
if (apt) {
|
||||
return apt;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
printf("search for unknown addon-ref '%s'\n", idname);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!quiet) {
|
||||
printf("search for empty addon");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void BKE_addon_pref_type_add(bAddonPrefType *apt)
|
||||
{
|
||||
BLI_ghash_insert(global_addonpreftype_hash, (void *)apt->idname, apt);
|
||||
}
|
||||
|
||||
void BKE_addon_pref_type_remove(bAddonPrefType *apt)
|
||||
{
|
||||
BLI_ghash_remove(global_addonpreftype_hash, (void *)apt->idname, NULL, (GHashValFreeFP)MEM_freeN);
|
||||
}
|
||||
|
||||
void BKE_addon_pref_type_init(void)
|
||||
{
|
||||
BLI_assert(global_addonpreftype_hash == NULL);
|
||||
global_addonpreftype_hash = BLI_ghash_str_new(__func__);
|
||||
}
|
||||
|
||||
void BKE_addon_pref_type_free(void)
|
||||
{
|
||||
BLI_ghash_free(global_addonpreftype_hash, NULL, (GHashValFreeFP)MEM_freeN);
|
||||
global_addonpreftype_hash = NULL;
|
||||
}
|
@ -387,6 +387,7 @@ void BKE_userdef_free(void)
|
||||
wmKeyMap *km;
|
||||
wmKeyMapItem *kmi;
|
||||
wmKeyMapDiffItem *kmdi;
|
||||
bAddon *addon, *addon_next;
|
||||
|
||||
for (km = U.user_keymaps.first; km; km = km->next) {
|
||||
for (kmdi = km->diff_items.first; kmdi; kmdi = kmdi->next) {
|
||||
@ -407,11 +408,19 @@ void BKE_userdef_free(void)
|
||||
BLI_freelistN(&km->items);
|
||||
}
|
||||
|
||||
for (addon = U.addons.first; addon; addon = addon_next) {
|
||||
addon_next = addon->next;
|
||||
if (addon->prop) {
|
||||
IDP_FreeProperty(addon->prop);
|
||||
MEM_freeN(addon->prop);
|
||||
}
|
||||
MEM_freeN(addon);
|
||||
}
|
||||
|
||||
BLI_freelistN(&U.uistyles);
|
||||
BLI_freelistN(&U.uifonts);
|
||||
BLI_freelistN(&U.themes);
|
||||
BLI_freelistN(&U.user_keymaps);
|
||||
BLI_freelistN(&U.addons);
|
||||
}
|
||||
|
||||
/* handle changes in settings that need recalc */
|
||||
|
@ -8646,6 +8646,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
||||
wmKeyMap *keymap;
|
||||
wmKeyMapItem *kmi;
|
||||
wmKeyMapDiffItem *kmdi;
|
||||
bAddon *addon;
|
||||
|
||||
bfd->user = user= read_struct(fd, bhead, "user def");
|
||||
|
||||
@ -8684,6 +8685,13 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
||||
direct_link_keymapitem(fd, kmi);
|
||||
}
|
||||
|
||||
for (addon = user->addons.first; addon; addon = addon->next) {
|
||||
addon->prop = newdataadr(fd, addon->prop);
|
||||
if (addon->prop) {
|
||||
IDP_DirectLinkProperty(addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX
|
||||
user->uifonts.first = user->uifonts.last= NULL;
|
||||
|
||||
|
@ -850,8 +850,12 @@ static void write_userdef(WriteData *wd)
|
||||
write_keymapitem(wd, kmi);
|
||||
}
|
||||
|
||||
for (bext= U.addons.first; bext; bext=bext->next)
|
||||
for (bext= U.addons.first; bext; bext=bext->next) {
|
||||
writestruct(wd, DATA, "bAddon", 1, bext);
|
||||
if (bext->prop) {
|
||||
IDP_WriteProperty(bext->prop, wd);
|
||||
}
|
||||
}
|
||||
|
||||
for (style= U.uistyles.first; style; style= style->next) {
|
||||
writestruct(wd, DATA, "uiStyle", 1, style);
|
||||
|
@ -343,6 +343,7 @@ typedef struct bTheme {
|
||||
typedef struct bAddon {
|
||||
struct bAddon *next, *prev;
|
||||
char module[64];
|
||||
IDProperty *prop; /* User-Defined Properties on this Addon (for storing preferences) */
|
||||
} bAddon;
|
||||
|
||||
typedef struct SolidLight {
|
||||
|
@ -54,6 +54,7 @@ extern StructRNA RNA_ActionPoseMarkers;
|
||||
extern StructRNA RNA_Actuator;
|
||||
extern StructRNA RNA_ActuatorSensor;
|
||||
extern StructRNA RNA_Addon;
|
||||
extern StructRNA RNA_AddonPreferences;
|
||||
extern StructRNA RNA_AdjustmentSequence;
|
||||
extern StructRNA RNA_AlwaysSensor;
|
||||
extern StructRNA RNA_AndController;
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "BLF_translation.h"
|
||||
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_addon.h"
|
||||
|
||||
#ifdef WITH_CYCLES
|
||||
static EnumPropertyItem compute_device_type_items[] = {
|
||||
@ -67,6 +68,7 @@ static EnumPropertyItem compute_device_type_items[] = {
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_idprop.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
|
||||
@ -79,6 +81,8 @@ static EnumPropertyItem compute_device_type_items[] = {
|
||||
|
||||
#include "CCL_api.h"
|
||||
|
||||
#include "BKE_addon.h"
|
||||
|
||||
static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
WM_main_add_notifier(NC_WINDOW, NULL);
|
||||
@ -428,6 +432,103 @@ static EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C), Poi
|
||||
}
|
||||
#endif
|
||||
|
||||
static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, int create)
|
||||
{
|
||||
if (create && !ptr->data) {
|
||||
IDPropertyTemplate val = {0};
|
||||
ptr->data = IDP_New(IDP_GROUP, &val, "RNA_AddonPreferences group");
|
||||
}
|
||||
|
||||
return ptr->data;
|
||||
}
|
||||
|
||||
static PointerRNA rna_Addon_preferences_get(PointerRNA *ptr)
|
||||
{
|
||||
bAddon *addon = (bAddon *)ptr->data;
|
||||
bAddonPrefType *apt = BKE_addon_pref_type_find(addon->module, TRUE);
|
||||
if (apt) {
|
||||
if (addon->prop == NULL) {
|
||||
IDPropertyTemplate val = {0};
|
||||
addon->prop = IDP_New(IDP_GROUP, &val, addon->module); /* name is unimportant */
|
||||
}
|
||||
return rna_pointer_inherit_refine(ptr, apt->ext.srna, addon->prop);
|
||||
}
|
||||
else {
|
||||
return PointerRNA_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type)
|
||||
{
|
||||
bAddonPrefType *apt = RNA_struct_blender_type_get(type);
|
||||
|
||||
if (!apt)
|
||||
return;
|
||||
|
||||
RNA_struct_free_extension(type, &apt->ext);
|
||||
|
||||
BKE_addon_pref_type_remove(apt);
|
||||
RNA_struct_free(&BLENDER_RNA, type);
|
||||
|
||||
/* update while blender is running */
|
||||
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
|
||||
StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
|
||||
{
|
||||
bAddonPrefType *apt, dummyapt = {{'\0'}};
|
||||
bAddon dummyaddon = {NULL};
|
||||
PointerRNA dummyhtr;
|
||||
// int have_function[1];
|
||||
|
||||
/* setup dummy header & header type to store static properties in */
|
||||
RNA_pointer_create(NULL, &RNA_AddonPreferences, &dummyaddon, &dummyhtr);
|
||||
|
||||
/* validate the python class */
|
||||
if (validate(&dummyhtr, data, NULL /* have_function */ ) != 0)
|
||||
return NULL;
|
||||
|
||||
BLI_strncpy(dummyapt.idname, dummyaddon.module, sizeof(dummyapt.idname));
|
||||
if (strlen(identifier) >= sizeof(dummyapt.idname)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Registering addon-prefs class: '%s' is too long, maximum length is %d",
|
||||
identifier, (int)sizeof(dummyapt.idname));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check if we have registered this header type before, and remove it */
|
||||
apt = BKE_addon_pref_type_find(dummyaddon.module, TRUE);
|
||||
if (apt) {
|
||||
if (apt->ext.srna) {
|
||||
rna_AddonPref_unregister(bmain, apt->ext.srna);
|
||||
}
|
||||
}
|
||||
|
||||
/* create a new header type */
|
||||
apt = MEM_mallocN(sizeof(bAddonPrefType), "addonpreftype");
|
||||
memcpy(apt, &dummyapt, sizeof(dummyapt));
|
||||
BKE_addon_pref_type_add(apt);
|
||||
|
||||
apt->ext.srna = RNA_def_struct(&BLENDER_RNA, identifier, "AddonPreferences");
|
||||
apt->ext.data = data;
|
||||
apt->ext.call = call;
|
||||
apt->ext.free = free;
|
||||
RNA_struct_blender_type_set(apt->ext.srna, apt);
|
||||
|
||||
// apt->draw = (have_function[0]) ? header_draw : NULL;
|
||||
|
||||
/* update while blender is running */
|
||||
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
|
||||
|
||||
return apt->ext.srna;
|
||||
}
|
||||
|
||||
/* placeholder, doesn't do anything useful yet */
|
||||
static StructRNA *rna_AddonPref_refine(PointerRNA *ptr)
|
||||
{
|
||||
return (ptr->type) ? ptr->type : &RNA_AddonPreferences;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
|
||||
@ -2381,6 +2482,32 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "module", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Module", "Module name");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
|
||||
/* Collection active property */
|
||||
prop = RNA_def_property(srna, "preferences", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "AddonPreferences");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_userdef_addon_pref(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "AddonPreferences", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Addon Preferences", "");
|
||||
RNA_def_struct_sdna(srna, "bAddon"); /* WARNING: only a bAddon during registration */
|
||||
|
||||
RNA_def_struct_refine_func(srna, "rna_AddonPref_refine");
|
||||
RNA_def_struct_register_funcs(srna, "rna_AddonPref_register", "rna_AddonPref_unregister", NULL);
|
||||
RNA_def_struct_idprops_func(srna, "rna_AddonPref_idprops");
|
||||
|
||||
/* registration */
|
||||
RNA_define_verify_sdna(0);
|
||||
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "module");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
|
||||
RNA_define_verify_sdna(1);
|
||||
}
|
||||
|
||||
|
||||
@ -3736,6 +3863,7 @@ void RNA_def_userdef(BlenderRNA *brna)
|
||||
rna_def_userdef_filepaths(brna);
|
||||
rna_def_userdef_system(brna);
|
||||
rna_def_userdef_addon(brna);
|
||||
rna_def_userdef_addon_pref(brna);
|
||||
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "BKE_addon.h"
|
||||
#include "BKE_packedFile.h"
|
||||
#include "BKE_sequencer.h" /* free seq clipboard */
|
||||
#include "BKE_material.h" /* clear_matcopybuf */
|
||||
@ -135,6 +136,9 @@ void WM_init(bContext *C, int argc, const char **argv)
|
||||
wm_init_cursor_data();
|
||||
}
|
||||
GHOST_CreateSystemPaths();
|
||||
|
||||
BKE_addon_pref_type_init();
|
||||
|
||||
wm_operatortype_init();
|
||||
WM_menutype_init();
|
||||
WM_uilisttype_init();
|
||||
@ -401,6 +405,8 @@ void WM_exit_ext(bContext *C, const short do_python)
|
||||
ED_screen_exit(C, win, win->screen);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_addon_pref_type_free();
|
||||
wm_operatortype_free();
|
||||
wm_dropbox_free();
|
||||
WM_menutype_free();
|
||||
|
Loading…
Reference in New Issue
Block a user