Merge branch 'blender-v3.3-release'
This commit is contained in:
commit
6ab5bced61
|
@ -952,6 +952,12 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
|
|||
uiItemS(layout);
|
||||
}
|
||||
|
||||
MenuType *mt_idtemplate_liboverride = WM_menutype_find("UI_MT_idtemplate_liboverride", true);
|
||||
if (mt_idtemplate_liboverride && mt_idtemplate_liboverride->poll(C, mt_idtemplate_liboverride)) {
|
||||
uiItemM_ptr(layout, mt_idtemplate_liboverride, IFACE_("Library Override"), ICON_NONE);
|
||||
uiItemS(layout);
|
||||
}
|
||||
|
||||
/* Pointer properties and string properties with
|
||||
* prop_search support jumping to target object/bone. */
|
||||
if (but->rnapoin.data && but->rnaprop) {
|
||||
|
|
|
@ -25,6 +25,7 @@ struct CurveMapping;
|
|||
struct CurveProfile;
|
||||
struct ID;
|
||||
struct ImBuf;
|
||||
struct Main;
|
||||
struct Scene;
|
||||
struct bContext;
|
||||
struct bContextStore;
|
||||
|
@ -1543,6 +1544,12 @@ uiButViewItem *ui_block_view_find_matching_view_item_but_in_old_block(
|
|||
|
||||
struct uiListType *UI_UL_cache_file_layers(void);
|
||||
|
||||
struct ID *ui_template_id_liboverride_hierarchy_create(struct bContext *C,
|
||||
struct Main *bmain,
|
||||
struct ID *owner_id,
|
||||
struct ID *id,
|
||||
const char **r_undo_push_label);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "BLF_api.h"
|
||||
#include "BLT_lang.h"
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_override.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_report.h"
|
||||
|
@ -747,6 +749,247 @@ static void UI_OT_override_remove_button(wmOperatorType *ot)
|
|||
ot->srna, "all", true, "All", "Reset to default values all elements of the array");
|
||||
}
|
||||
|
||||
static void override_idtemplate_ids_get(
|
||||
bContext *C, ID **r_owner_id, ID **r_id, PointerRNA *r_owner_ptr, PropertyRNA **r_prop)
|
||||
{
|
||||
PointerRNA owner_ptr;
|
||||
PropertyRNA *prop;
|
||||
UI_context_active_but_prop_get_templateID(C, &owner_ptr, &prop);
|
||||
|
||||
if (owner_ptr.data == NULL || prop == NULL) {
|
||||
*r_owner_id = *r_id = NULL;
|
||||
if (r_owner_ptr != NULL) {
|
||||
*r_owner_ptr = PointerRNA_NULL;
|
||||
}
|
||||
if (r_prop != NULL) {
|
||||
*r_prop = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
*r_owner_id = owner_ptr.owner_id;
|
||||
PointerRNA idptr = RNA_property_pointer_get(&owner_ptr, prop);
|
||||
*r_id = idptr.data;
|
||||
if (r_owner_ptr != NULL) {
|
||||
*r_owner_ptr = owner_ptr;
|
||||
}
|
||||
if (r_prop != NULL) {
|
||||
*r_prop = prop;
|
||||
}
|
||||
}
|
||||
|
||||
static bool override_idtemplate_poll(bContext *C, const bool is_create_op)
|
||||
{
|
||||
ID *owner_id, *id;
|
||||
override_idtemplate_ids_get(C, &owner_id, &id, NULL, NULL);
|
||||
|
||||
if (owner_id == NULL || id == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_create_op) {
|
||||
if (!ID_IS_LINKED(id) && !ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Reset/Clear operations. */
|
||||
if (ID_IS_LINKED(id) || !ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool override_idtemplate_create_poll(bContext *C)
|
||||
{
|
||||
return override_idtemplate_poll(C, true);
|
||||
}
|
||||
|
||||
static int override_idtemplate_create_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ID *owner_id, *id;
|
||||
PointerRNA owner_ptr;
|
||||
PropertyRNA *prop;
|
||||
override_idtemplate_ids_get(C, &owner_id, &id, &owner_ptr, &prop);
|
||||
if (ELEM(NULL, owner_id, id)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
ID *id_override = ui_template_id_liboverride_hierarchy_create(
|
||||
C, CTX_data_main(C), owner_id, id, NULL);
|
||||
|
||||
if (id_override == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
PointerRNA idptr;
|
||||
/* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it to
|
||||
* ensure remapping of the owner property from the linked data to the newly created liboverride
|
||||
* (note that in theory this remapping has already been done by code above). */
|
||||
RNA_id_pointer_create(id_override, &idptr);
|
||||
RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL);
|
||||
RNA_property_update(C, &owner_ptr, prop);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UI_OT_override_idtemplate_create(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Create Library Override";
|
||||
ot->idname = "UI_OT_override_idtemplate_create";
|
||||
ot->description =
|
||||
"Create a local override of the selected linked data-block, and its hierarchy of "
|
||||
"dependencies";
|
||||
|
||||
/* callbacks */
|
||||
ot->poll = override_idtemplate_create_poll;
|
||||
ot->exec = override_idtemplate_create_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static bool override_idtemplate_reset_poll(bContext *C)
|
||||
{
|
||||
return override_idtemplate_poll(C, false);
|
||||
}
|
||||
|
||||
static int override_idtemplate_reset_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ID *owner_id, *id;
|
||||
PointerRNA owner_ptr;
|
||||
PropertyRNA *prop;
|
||||
override_idtemplate_ids_get(C, &owner_id, &id, &owner_ptr, &prop);
|
||||
if (ELEM(NULL, owner_id, id)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (ID_IS_LINKED(id) || !ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_lib_override_library_id_reset(CTX_data_main(C), id, false);
|
||||
|
||||
PointerRNA idptr;
|
||||
/* `idptr` is re-assigned to owner property to ensure proper updates etc. */
|
||||
RNA_id_pointer_create(id, &idptr);
|
||||
RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL);
|
||||
RNA_property_update(C, &owner_ptr, prop);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UI_OT_override_idtemplate_reset(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Reset Library Override";
|
||||
ot->idname = "UI_OT_override_idtemplate_reset";
|
||||
ot->description = "Reset the selected local override to its linked reference values";
|
||||
|
||||
/* callbacks */
|
||||
ot->poll = override_idtemplate_reset_poll;
|
||||
ot->exec = override_idtemplate_reset_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static bool override_idtemplate_clear_poll(bContext *C)
|
||||
{
|
||||
return override_idtemplate_poll(C, false);
|
||||
}
|
||||
|
||||
static int override_idtemplate_clear_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ID *owner_id, *id;
|
||||
PointerRNA owner_ptr;
|
||||
PropertyRNA *prop;
|
||||
override_idtemplate_ids_get(C, &owner_id, &id, &owner_ptr, &prop);
|
||||
if (ELEM(NULL, owner_id, id)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (ID_IS_LINKED(id)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ID *id_new = id;
|
||||
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, id)) {
|
||||
id_new = id->override_library->reference;
|
||||
BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
BKE_id_delete(bmain, id);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_id_reset(bmain, id, true);
|
||||
}
|
||||
|
||||
PointerRNA idptr;
|
||||
/* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it to
|
||||
* ensure remapping of the owner property from the linked data to the newly created liboverride
|
||||
* (note that in theory this remapping has already been done by code above). */
|
||||
RNA_id_pointer_create(id_new, &idptr);
|
||||
RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL);
|
||||
RNA_property_update(C, &owner_ptr, prop);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UI_OT_override_idtemplate_clear(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Clear Library Override";
|
||||
ot->idname = "UI_OT_override_idtemplate_clear";
|
||||
ot->description =
|
||||
"Delete the selected local override and relink its usages to the linked data-block if "
|
||||
"possible, else reset it and mark it as non editable";
|
||||
|
||||
/* callbacks */
|
||||
ot->poll = override_idtemplate_clear_poll;
|
||||
ot->exec = override_idtemplate_clear_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static bool override_idtemplate_menu_poll(const bContext *C_const, MenuType *UNUSED(mt))
|
||||
{
|
||||
bContext *C = (bContext *)C_const;
|
||||
ID *owner_id, *id;
|
||||
override_idtemplate_ids_get(C, &owner_id, &id, NULL, NULL);
|
||||
|
||||
if (owner_id == NULL || id == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(ID_IS_LINKED(id) || ID_IS_OVERRIDE_LIBRARY_REAL(id))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void override_idtemplate_menu_draw(const bContext *UNUSED(C), Menu *menu)
|
||||
{
|
||||
uiLayout *layout = menu->layout;
|
||||
uiItemO(layout, IFACE_("Make"), ICON_NONE, "UI_OT_override_idtemplate_create");
|
||||
uiItemO(layout, IFACE_("Reset"), ICON_NONE, "UI_OT_override_idtemplate_reset");
|
||||
uiItemO(layout, IFACE_("Clear"), ICON_NONE, "UI_OT_override_idtemplate_clear");
|
||||
}
|
||||
|
||||
static void override_idtemplate_menu(void)
|
||||
{
|
||||
MenuType *mt;
|
||||
|
||||
mt = MEM_callocN(sizeof(MenuType), __func__);
|
||||
strcpy(mt->idname, "UI_MT_idtemplate_liboverride");
|
||||
strcpy(mt->label, N_("Library Override"));
|
||||
mt->poll = override_idtemplate_menu_poll;
|
||||
mt->draw = override_idtemplate_menu_draw;
|
||||
WM_menutype_add(mt);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -2232,8 +2475,6 @@ void ED_operatortypes_ui(void)
|
|||
WM_operatortype_append(UI_OT_reset_default_button);
|
||||
WM_operatortype_append(UI_OT_assign_default_button);
|
||||
WM_operatortype_append(UI_OT_unset_property_button);
|
||||
WM_operatortype_append(UI_OT_override_type_set_button);
|
||||
WM_operatortype_append(UI_OT_override_remove_button);
|
||||
WM_operatortype_append(UI_OT_copy_to_selected_button);
|
||||
WM_operatortype_append(UI_OT_jump_to_target_button);
|
||||
WM_operatortype_append(UI_OT_drop_color);
|
||||
|
@ -2252,6 +2493,13 @@ void ED_operatortypes_ui(void)
|
|||
WM_operatortype_append(UI_OT_view_drop);
|
||||
WM_operatortype_append(UI_OT_view_item_rename);
|
||||
|
||||
WM_operatortype_append(UI_OT_override_type_set_button);
|
||||
WM_operatortype_append(UI_OT_override_remove_button);
|
||||
WM_operatortype_append(UI_OT_override_idtemplate_create);
|
||||
WM_operatortype_append(UI_OT_override_idtemplate_reset);
|
||||
WM_operatortype_append(UI_OT_override_idtemplate_clear);
|
||||
override_idtemplate_menu();
|
||||
|
||||
/* external */
|
||||
WM_operatortype_append(UI_OT_eyedropper_color);
|
||||
WM_operatortype_append(UI_OT_eyedropper_colorramp);
|
||||
|
|
|
@ -650,14 +650,13 @@ static void template_id_liboverride_hierarchy_collections_tag_recursive(
|
|||
}
|
||||
}
|
||||
|
||||
static void template_id_liboverride_hierarchy_create(bContext *C,
|
||||
Main *bmain,
|
||||
TemplateID *template_ui,
|
||||
PointerRNA *idptr,
|
||||
const char **r_undo_push_label)
|
||||
ID *ui_template_id_liboverride_hierarchy_create(
|
||||
bContext *C, Main *bmain, ID *owner_id, ID *id, const char **r_undo_push_label)
|
||||
{
|
||||
ID *id = idptr->data;
|
||||
ID *owner_id = template_ui->ptr.owner_id;
|
||||
const char *undo_push_label;
|
||||
if (r_undo_push_label == NULL) {
|
||||
r_undo_push_label = &undo_push_label;
|
||||
}
|
||||
|
||||
/* If this is called on an already local override, 'toggle' between user-editable state, and
|
||||
* system override with reset. */
|
||||
|
@ -677,7 +676,7 @@ static void template_id_liboverride_hierarchy_create(bContext *C,
|
|||
WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
return;
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Attempt to perform a hierarchy override, based on contextual data available.
|
||||
|
@ -685,7 +684,7 @@ static void template_id_liboverride_hierarchy_create(bContext *C,
|
|||
* context, better to abort than create random overrides all over the place. */
|
||||
if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(id)) {
|
||||
RNA_warning("The data-block %s is not direclty overridable", id->name);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Object *object_active = CTX_data_active_object(C);
|
||||
|
@ -867,7 +866,23 @@ static void template_id_liboverride_hierarchy_create(bContext *C,
|
|||
if (id_override != NULL) {
|
||||
id_override->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
|
||||
*r_undo_push_label = "Make Library Override Hierarchy";
|
||||
}
|
||||
return id_override;
|
||||
}
|
||||
|
||||
static void template_id_liboverride_hierarchy_create(bContext *C,
|
||||
Main *bmain,
|
||||
TemplateID *template_ui,
|
||||
PointerRNA *idptr,
|
||||
const char **r_undo_push_label)
|
||||
{
|
||||
ID *id = idptr->data;
|
||||
ID *owner_id = template_ui->ptr.owner_id;
|
||||
|
||||
ID *id_override = ui_template_id_liboverride_hierarchy_create(
|
||||
C, bmain, owner_id, id, r_undo_push_label);
|
||||
|
||||
if (id_override != NULL) {
|
||||
/* Given `idptr` is re-assigned to owner property by caller to ensure proper updates etc. Here
|
||||
* we also use it to ensure remapping of the owner property from the linked data to the newly
|
||||
* created liboverride (note that in theory this remapping has already been done by code
|
||||
|
|
Loading…
Reference in New Issue