Compare commits
43 Commits
temp-colle
...
temp-outli
Author | SHA1 | Date | |
---|---|---|---|
3210cb0af5 | |||
50e38a066c | |||
178ce8bbad | |||
da5159b2f2 | |||
482936fc33 | |||
b261022ae3 | |||
00a0108cc7 | |||
7cddc047ba | |||
10932d9663 | |||
b49e972628 | |||
fbc3e0c92f | |||
43d044ee03 | |||
f2f86002bf | |||
dddf793f75 | |||
27963594f4 | |||
10cf94669b | |||
9bb71e2fbe | |||
fe0a65512f | |||
90960891bc | |||
ad19133051 | |||
a6c00778c2 | |||
f28be6d7e0 | |||
bc994918d3 | |||
d2fd15e314 | |||
d71a1845f0 | |||
1cc2b2c5ac | |||
0ee86098e3 | |||
1dbc8876dd | |||
aa9b84d453 | |||
e4b5965463 | |||
838065b152 | |||
8624732e9b | |||
5b72bb108d | |||
96f2be2a05 | |||
439f5c02c4 | |||
bc952941c7 | |||
ae1d1839d0 | |||
c47b8dab51 | |||
13c5e8336f | |||
03117c0875 | |||
13fe40b5d0 | |||
fa975dfb34 | |||
f673b9c8b1 |
@@ -10,6 +10,8 @@
|
|||||||
/* XXX temporary, until AssetHandle is designed properly and queries can return a pointer to it. */
|
/* XXX temporary, until AssetHandle is designed properly and queries can return a pointer to it. */
|
||||||
#include "DNA_asset_types.h"
|
#include "DNA_asset_types.h"
|
||||||
|
|
||||||
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "DNA_listBase.h"
|
#include "DNA_listBase.h"
|
||||||
#include "DNA_object_enums.h"
|
#include "DNA_object_enums.h"
|
||||||
#include "RNA_types.h"
|
#include "RNA_types.h"
|
||||||
@@ -136,6 +138,9 @@ bContextStore *CTX_store_add(ListBase *contexts, const char *name, const Pointer
|
|||||||
bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context);
|
bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context);
|
||||||
bContextStore *CTX_store_get(bContext *C);
|
bContextStore *CTX_store_get(bContext *C);
|
||||||
void CTX_store_set(bContext *C, bContextStore *store);
|
void CTX_store_set(bContext *C, bContextStore *store);
|
||||||
|
const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store,
|
||||||
|
const char *name,
|
||||||
|
const StructRNA *type CPP_ARG_DEFAULT(nullptr));
|
||||||
bContextStore *CTX_store_copy(bContextStore *store);
|
bContextStore *CTX_store_copy(bContextStore *store);
|
||||||
void CTX_store_free(bContextStore *store);
|
void CTX_store_free(bContextStore *store);
|
||||||
void CTX_store_free_list(ListBase *contexts);
|
void CTX_store_free_list(ListBase *contexts);
|
||||||
|
@@ -190,6 +190,22 @@ void CTX_store_set(bContext *C, bContextStore *store)
|
|||||||
C->wm.store = store;
|
C->wm.store = store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store,
|
||||||
|
const char *name,
|
||||||
|
const StructRNA *type)
|
||||||
|
{
|
||||||
|
bContextStoreEntry *entry = BLI_rfindstring(
|
||||||
|
&store->entries, name, offsetof(bContextStoreEntry, name));
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type && !RNA_struct_is_a(entry->ptr.type, type)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &entry->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
bContextStore *CTX_store_copy(bContextStore *store)
|
bContextStore *CTX_store_copy(bContextStore *store)
|
||||||
{
|
{
|
||||||
bContextStore *ctx = MEM_dupallocN(store);
|
bContextStore *ctx = MEM_dupallocN(store);
|
||||||
@@ -324,11 +340,10 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData
|
|||||||
if (done != 1 && recursion < 1 && C->wm.store) {
|
if (done != 1 && recursion < 1 && C->wm.store) {
|
||||||
C->data.recursion = 1;
|
C->data.recursion = 1;
|
||||||
|
|
||||||
bContextStoreEntry *entry = BLI_rfindstring(
|
const PointerRNA *ptr = CTX_store_ptr_lookup(C->wm.store, member, NULL);
|
||||||
&C->wm.store->entries, member, offsetof(bContextStoreEntry, name));
|
|
||||||
|
|
||||||
if (entry) {
|
if (ptr) {
|
||||||
result->ptr = entry->ptr;
|
result->ptr = *ptr;
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -508,6 +508,10 @@ typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
|
|||||||
typedef void (*uiButHandleHoldFunc)(struct bContext *C, struct ARegion *butregion, uiBut *but);
|
typedef void (*uiButHandleHoldFunc)(struct bContext *C, struct ARegion *butregion, uiBut *but);
|
||||||
typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
|
typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
|
||||||
|
|
||||||
|
/** Function to compare the identity of two buttons over redraws, to check if they represent the
|
||||||
|
* same data, and thus should be considered the same button over redraws. */
|
||||||
|
typedef bool (*uiButIdentityCompareFunc)(const uiBut *a, const uiBut *b);
|
||||||
|
|
||||||
/* Search types. */
|
/* Search types. */
|
||||||
typedef struct ARegion *(*uiButSearchCreateFn)(struct bContext *C,
|
typedef struct ARegion *(*uiButSearchCreateFn)(struct bContext *C,
|
||||||
struct ARegion *butregion,
|
struct ARegion *butregion,
|
||||||
@@ -1360,6 +1364,13 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block,
|
|||||||
/* for passing inputs to ButO buttons */
|
/* for passing inputs to ButO buttons */
|
||||||
struct PointerRNA *UI_but_operator_ptr_get(uiBut *but);
|
struct PointerRNA *UI_but_operator_ptr_get(uiBut *but);
|
||||||
|
|
||||||
|
void UI_but_context_ptr_set(uiBlock *block,
|
||||||
|
uiBut *but,
|
||||||
|
const char *name,
|
||||||
|
const struct PointerRNA *ptr);
|
||||||
|
const struct PointerRNA *UI_but_context_ptr_get(const uiBut *but,
|
||||||
|
const char *name,
|
||||||
|
const StructRNA *type CPP_ARG_DEFAULT(nullptr));
|
||||||
struct bContextStore *UI_but_context_get(const uiBut *but);
|
struct bContextStore *UI_but_context_get(const uiBut *but);
|
||||||
|
|
||||||
void UI_but_unit_type_set(uiBut *but, int unit_type);
|
void UI_but_unit_type_set(uiBut *but, int unit_type);
|
||||||
@@ -1642,6 +1653,18 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
|
|||||||
eButLabelAlign label_align,
|
eButLabelAlign label_align,
|
||||||
bool compact);
|
bool compact);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to compare the identity of two buttons, used to identify buttons over redraws. If the
|
||||||
|
* callback returns true, the given buttons are considered to be matching and relevant state is
|
||||||
|
* preserved (copied from the old to the new button). If it returns false, it's considered
|
||||||
|
* non-matching and no further checks are done.
|
||||||
|
*
|
||||||
|
* If this is set, it is always executed instead of the default comparisons. However it is only
|
||||||
|
* executed for buttons that have the same type and the same callback. So callbacks can assume the
|
||||||
|
* button types match.
|
||||||
|
*/
|
||||||
|
void UI_but_func_identity_compare_set(uiBut *but, uiButIdentityCompareFunc cmp_fn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public function exported for functions that use #UI_BTYPE_SEARCH_MENU.
|
* Public function exported for functions that use #UI_BTYPE_SEARCH_MENU.
|
||||||
*
|
*
|
||||||
|
@@ -725,6 +725,19 @@ bool ui_but_rna_equals_ex(const uiBut *but,
|
|||||||
/* NOTE: if `but->poin` is allocated memory for every `uiDefBut*`, things fail. */
|
/* NOTE: if `but->poin` is allocated memory for every `uiDefBut*`, things fail. */
|
||||||
static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
|
static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
|
||||||
{
|
{
|
||||||
|
if (but->identity_cmp_func) {
|
||||||
|
/* If the buttons have own identity comparator callbacks (and they match), use this to
|
||||||
|
* determine equality. */
|
||||||
|
if (but->identity_cmp_func && (but->type == oldbut->type) &&
|
||||||
|
(but->identity_cmp_func == oldbut->identity_cmp_func)) {
|
||||||
|
/* Test if the comparison is symmetrical (if a == b then b == a), may help catch some issues.
|
||||||
|
*/
|
||||||
|
BLI_assert(but->identity_cmp_func(but, oldbut) == but->identity_cmp_func(oldbut, but));
|
||||||
|
|
||||||
|
return but->identity_cmp_func(but, oldbut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* various properties are being compared here, hopefully sufficient
|
/* various properties are being compared here, hopefully sufficient
|
||||||
* to catch all cases, but it is simple to add more checks later */
|
* to catch all cases, but it is simple to add more checks later */
|
||||||
if (but->retval != oldbut->retval) {
|
if (but->retval != oldbut->retval) {
|
||||||
@@ -5951,6 +5964,17 @@ PointerRNA *UI_but_operator_ptr_get(uiBut *but)
|
|||||||
return but->opptr;
|
return but->opptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UI_but_context_ptr_set(uiBlock *block, uiBut *but, const char *name, const PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
but->context = CTX_store_add(&block->contexts, name, ptr);
|
||||||
|
but->context->used = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PointerRNA *UI_but_context_ptr_get(const uiBut *but, const char *name, const StructRNA *type)
|
||||||
|
{
|
||||||
|
return CTX_store_ptr_lookup(but->context, name, type);
|
||||||
|
}
|
||||||
|
|
||||||
bContextStore *UI_but_context_get(const uiBut *but)
|
bContextStore *UI_but_context_get(const uiBut *but)
|
||||||
{
|
{
|
||||||
return but->context;
|
return but->context;
|
||||||
|
@@ -183,6 +183,9 @@ struct uiBut {
|
|||||||
|
|
||||||
uchar col[4];
|
uchar col[4];
|
||||||
|
|
||||||
|
/** See \ref UI_but_func_identity_compare_set(). */
|
||||||
|
uiButIdentityCompareFunc identity_cmp_func;
|
||||||
|
|
||||||
uiButHandleFunc func;
|
uiButHandleFunc func;
|
||||||
void *func_arg1;
|
void *func_arg1;
|
||||||
void *func_arg2;
|
void *func_arg2;
|
||||||
|
@@ -452,6 +452,11 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
|
|||||||
return return_info;
|
return return_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UI_but_func_identity_compare_set(uiBut *but, uiButIdentityCompareFunc cmp_fn)
|
||||||
|
{
|
||||||
|
but->identity_cmp_func = cmp_fn;
|
||||||
|
}
|
||||||
|
|
||||||
/* *** RNA collection search menu *** */
|
/* *** RNA collection search menu *** */
|
||||||
|
|
||||||
struct CollItemSearch {
|
struct CollItemSearch {
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
#include "BKE_idtype.h"
|
#include "BKE_idtype.h"
|
||||||
#include "BKE_layer.h"
|
#include "BKE_layer.h"
|
||||||
#include "BKE_lib_id.h"
|
#include "BKE_lib_id.h"
|
||||||
|
#include "BKE_lib_override.h"
|
||||||
#include "BKE_library.h"
|
#include "BKE_library.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
#include "BKE_modifier.h"
|
#include "BKE_modifier.h"
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
#include "outliner_intern.hh"
|
#include "outliner_intern.hh"
|
||||||
#include "tree/tree_display.hh"
|
#include "tree/tree_display.hh"
|
||||||
#include "tree/tree_element.hh"
|
#include "tree/tree_element.hh"
|
||||||
|
#include "tree/tree_element_id.hh"
|
||||||
#include "tree/tree_element_overrides.hh"
|
#include "tree/tree_element_overrides.hh"
|
||||||
#include "tree/tree_element_rna.hh"
|
#include "tree/tree_element_rna.hh"
|
||||||
|
|
||||||
@@ -1835,6 +1837,69 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool outliner_but_identity_cmp_context_id_fn(const uiBut *a, const uiBut *b)
|
||||||
|
{
|
||||||
|
const PointerRNA *idptr_a = UI_but_context_ptr_get(a, "id", &RNA_ID);
|
||||||
|
const PointerRNA *idptr_b = UI_but_context_ptr_get(b, "id", &RNA_ID);
|
||||||
|
if (!idptr_a || !idptr_b) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const ID *id_a = (const ID *)idptr_a->data;
|
||||||
|
const ID *id_b = (const ID *)idptr_b->data;
|
||||||
|
|
||||||
|
/* Using session UUID to compare is safer than using the pointer. */
|
||||||
|
return id_a->session_uuid == id_b->session_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void outliner_draw_overrides_restrictbuts(Main *bmain,
|
||||||
|
uiBlock *block,
|
||||||
|
const ARegion *region,
|
||||||
|
const SpaceOutliner *space_outliner,
|
||||||
|
const ListBase *lb,
|
||||||
|
const int x)
|
||||||
|
{
|
||||||
|
LISTBASE_FOREACH (const TreeElement *, te, lb) {
|
||||||
|
const TreeStoreElem *tselem = TREESTORE(te);
|
||||||
|
if (TSELEM_OPEN(tselem, space_outliner)) {
|
||||||
|
outliner_draw_overrides_restrictbuts(bmain, block, region, space_outliner, &te->subtree, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outliner_is_element_in_view(te, ®ion->v2d)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TreeElementID *te_id = tree_element_cast<TreeElementID>(te);
|
||||||
|
if (!te_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID &id = te_id->get_ID();
|
||||||
|
BLI_assert(ID_IS_OVERRIDE_LIBRARY(&id));
|
||||||
|
|
||||||
|
if (ID_IS_LINKED(&id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool is_system_override = BKE_lib_override_library_is_system_defined(bmain, &id);
|
||||||
|
const BIFIconID icon = is_system_override ? ICON_LIBRARY_DATA_OVERRIDE_NONEDITABLE :
|
||||||
|
ICON_LIBRARY_DATA_OVERRIDE;
|
||||||
|
uiBut *but = uiDefIconButO(block,
|
||||||
|
UI_BTYPE_BUT,
|
||||||
|
"ED_OT_lib_id_override_editable_toggle",
|
||||||
|
WM_OP_EXEC_DEFAULT,
|
||||||
|
icon,
|
||||||
|
x,
|
||||||
|
te->ys,
|
||||||
|
UI_UNIT_X,
|
||||||
|
UI_UNIT_Y,
|
||||||
|
"");
|
||||||
|
PointerRNA idptr;
|
||||||
|
RNA_id_pointer_create(&id, &idptr);
|
||||||
|
UI_but_context_ptr_set(block, but, "id", &idptr);
|
||||||
|
UI_but_func_identity_compare_set(but, outliner_but_identity_cmp_context_id_fn);
|
||||||
|
UI_but_flag_enable(but, UI_BUT_DRAG_LOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool outliner_draw_overrides_warning_buts(uiBlock *block,
|
static bool outliner_draw_overrides_warning_buts(uiBlock *block,
|
||||||
ARegion *region,
|
ARegion *region,
|
||||||
SpaceOutliner *space_outliner,
|
SpaceOutliner *space_outliner,
|
||||||
@@ -3899,12 +3964,6 @@ void draw_outliner(const bContext *C)
|
|||||||
/* Default to no emboss for outliner UI. */
|
/* Default to no emboss for outliner UI. */
|
||||||
UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
|
UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
|
||||||
|
|
||||||
if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) {
|
|
||||||
/* Draw overrides status columns. */
|
|
||||||
outliner_draw_overrides_warning_buts(
|
|
||||||
block, region, space_outliner, &space_outliner->tree, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (space_outliner->outlinevis == SO_DATA_API) {
|
if (space_outliner->outlinevis == SO_DATA_API) {
|
||||||
int buttons_start_x = outliner_data_api_buttons_start_x(tree_width);
|
int buttons_start_x = outliner_data_api_buttons_start_x(tree_width);
|
||||||
/* draw rna buttons */
|
/* draw rna buttons */
|
||||||
@@ -3919,14 +3978,23 @@ void draw_outliner(const bContext *C)
|
|||||||
/* draw user toggle columns */
|
/* draw user toggle columns */
|
||||||
outliner_draw_userbuts(block, region, space_outliner, &space_outliner->tree);
|
outliner_draw_userbuts(block, region, space_outliner, &space_outliner->tree);
|
||||||
}
|
}
|
||||||
else if ((space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) &&
|
else if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) {
|
||||||
(space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_PROPERTIES)) {
|
/* Draw overrides status columns. */
|
||||||
UI_block_emboss_set(block, UI_EMBOSS);
|
outliner_draw_overrides_warning_buts(
|
||||||
UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE);
|
block, region, space_outliner, &space_outliner->tree, true);
|
||||||
|
|
||||||
const int x = region->v2d.cur.xmax - right_column_width;
|
const int x = region->v2d.cur.xmax - right_column_width;
|
||||||
outliner_draw_separator(region, x);
|
outliner_draw_separator(region, x);
|
||||||
outliner_draw_overrides_rna_buts(block, region, space_outliner, &space_outliner->tree, x);
|
if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_PROPERTIES) {
|
||||||
UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
|
UI_block_emboss_set(block, UI_EMBOSS);
|
||||||
|
UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE);
|
||||||
|
outliner_draw_overrides_rna_buts(block, region, space_outliner, &space_outliner->tree, x);
|
||||||
|
UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS);
|
||||||
|
}
|
||||||
|
else if (space_outliner->lib_override_view_mode == SO_LIB_OVERRIDE_VIEW_HIERARCHIES) {
|
||||||
|
outliner_draw_overrides_restrictbuts(
|
||||||
|
mainvar, block, region, space_outliner, &space_outliner->tree, x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (right_column_width > 0.0f) {
|
else if (right_column_width > 0.0f) {
|
||||||
/* draw restriction columns */
|
/* draw restriction columns */
|
||||||
|
@@ -324,10 +324,14 @@ float outliner_right_columns_width(const SpaceOutliner *space_outliner)
|
|||||||
case SO_LIBRARIES:
|
case SO_LIBRARIES:
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
case SO_OVERRIDES_LIBRARY:
|
case SO_OVERRIDES_LIBRARY:
|
||||||
if (space_outliner->lib_override_view_mode != SO_LIB_OVERRIDE_VIEW_PROPERTIES) {
|
switch ((eSpaceOutliner_LibOverrideViewMode)space_outliner->lib_override_view_mode) {
|
||||||
return 0.0f;
|
case SO_LIB_OVERRIDE_VIEW_PROPERTIES:
|
||||||
|
num_columns = OL_RNA_COL_SIZEX / UI_UNIT_X;
|
||||||
|
break;
|
||||||
|
case SO_LIB_OVERRIDE_VIEW_HIERARCHIES:
|
||||||
|
num_columns = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
num_columns = OL_RNA_COL_SIZEX / UI_UNIT_X;
|
|
||||||
break;
|
break;
|
||||||
case SO_ID_ORPHANS:
|
case SO_ID_ORPHANS:
|
||||||
num_columns = 3;
|
num_columns = 3;
|
||||||
|
@@ -18,6 +18,8 @@ set(INC
|
|||||||
../../../../intern/clog
|
../../../../intern/clog
|
||||||
../../../../intern/glew-mx
|
../../../../intern/glew-mx
|
||||||
../../../../intern/guardedalloc
|
../../../../intern/guardedalloc
|
||||||
|
# RNA_prototypes.h
|
||||||
|
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -110,3 +112,6 @@ if(WITH_PYTHON)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
blender_add_lib(bf_editor_util "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
blender_add_lib(bf_editor_util "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||||
|
|
||||||
|
# RNA_prototypes.h
|
||||||
|
add_dependencies(bf_editor_util bf_rna)
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_icons.h"
|
#include "BKE_icons.h"
|
||||||
#include "BKE_lib_id.h"
|
#include "BKE_lib_id.h"
|
||||||
|
#include "BKE_lib_override.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
#include "BKE_report.h"
|
#include "BKE_report.h"
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
#include "ED_util.h"
|
#include "ED_util.h"
|
||||||
|
|
||||||
#include "RNA_access.h"
|
#include "RNA_access.h"
|
||||||
|
#include "RNA_prototypes.h"
|
||||||
|
|
||||||
#include "UI_interface.h"
|
#include "UI_interface.h"
|
||||||
|
|
||||||
@@ -294,6 +296,50 @@ static void ED_OT_lib_id_unlink(wmOperatorType *ot)
|
|||||||
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool lib_id_override_editable_toggle_poll(bContext *C)
|
||||||
|
{
|
||||||
|
const PointerRNA id_ptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
|
||||||
|
const ID *id = static_cast<ID *>(id_ptr.data);
|
||||||
|
|
||||||
|
return id && ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_id_override_editable_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
|
{
|
||||||
|
Main *bmain = CTX_data_main(C);
|
||||||
|
const PointerRNA id_ptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
|
||||||
|
ID *id = static_cast<ID *>(id_ptr.data);
|
||||||
|
|
||||||
|
const bool is_system_override = BKE_lib_override_library_is_system_defined(bmain, id);
|
||||||
|
if (is_system_override) {
|
||||||
|
/* A system override is not editable. Make it an editable (non-system-defined) one. */
|
||||||
|
id->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Reset override, which makes it non-editable (i.e. a system define override). */
|
||||||
|
BKE_lib_override_library_id_reset(bmain, id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, nullptr);
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ED_OT_lib_id_override_editable_toggle(wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
/* identifiers */
|
||||||
|
ot->name = "Toggle Library Override Editable";
|
||||||
|
ot->description = "Set if this library override data-block can be edited";
|
||||||
|
ot->idname = "ED_OT_lib_id_override_editable_toggle";
|
||||||
|
|
||||||
|
/* api callbacks */
|
||||||
|
ot->poll = lib_id_override_editable_toggle_poll;
|
||||||
|
ot->exec = lib_id_override_editable_toggle_exec;
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -331,6 +377,7 @@ void ED_operatortypes_edutils()
|
|||||||
|
|
||||||
WM_operatortype_append(ED_OT_lib_id_fake_user_toggle);
|
WM_operatortype_append(ED_OT_lib_id_fake_user_toggle);
|
||||||
WM_operatortype_append(ED_OT_lib_id_unlink);
|
WM_operatortype_append(ED_OT_lib_id_unlink);
|
||||||
|
WM_operatortype_append(ED_OT_lib_id_override_editable_toggle);
|
||||||
|
|
||||||
WM_operatortype_append(ED_OT_flush_edits);
|
WM_operatortype_append(ED_OT_flush_edits);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user