diff options
Diffstat (limited to 'source/blender/editors/object/object_edit.c')
-rw-r--r-- | source/blender/editors/object/object_edit.c | 107 |
1 files changed, 71 insertions, 36 deletions
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index b9a7da02611..a2e91761a38 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1506,11 +1506,12 @@ bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_onl static int move_to_collection_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); PropertyRNA *prop = RNA_struct_find_property(op->ptr, "collection_index"); - const bool is_add = RNA_boolean_get(op->ptr, "is_add"); + const bool is_link = STREQ(op->idname, "OBJECT_OT_link_to_collection"); const bool is_new = RNA_boolean_get(op->ptr, "is_new"); - SceneCollection *scene_collection; + Collection *collection; if (!RNA_property_is_set(op->ptr, prop)) { BKE_report(op->reports, RPT_ERROR, "No collection selected"); @@ -1518,8 +1519,8 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) } int collection_index = RNA_property_int_get(op->ptr, prop); - scene_collection = BKE_collection_from_index(CTX_data_scene(C), collection_index); - if (scene_collection == NULL) { + collection = BKE_collection_from_index(CTX_data_scene(C), collection_index); + if (collection == NULL) { BKE_report(op->reports, RPT_ERROR, "Unexpected error, collection not found"); return OPERATOR_CANCELLED; } @@ -1540,24 +1541,24 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) if (is_new) { char new_collection_name[MAX_NAME]; RNA_string_get(op->ptr, "new_collection_name", new_collection_name); - scene_collection = BKE_collection_add(&scene->id, scene_collection, COLLECTION_TYPE_NONE, new_collection_name); + collection = BKE_collection_add(bmain, collection, new_collection_name); } if ((single_object != NULL) && - is_add && - BLI_findptr(&scene_collection->objects, single_object, offsetof(LinkData, data))) + is_link && + BLI_findptr(&collection->gobject, single_object, offsetof(CollectionObject, ob))) { - BKE_reportf(op->reports, RPT_ERROR, "%s already in %s", single_object->id.name + 2, scene_collection->name); + BKE_reportf(op->reports, RPT_ERROR, "%s already in %s", single_object->id.name + 2, collection->id.name + 2); return OPERATOR_CANCELLED; } CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { - if (!is_add) { - BKE_collection_object_move(&scene->id, scene_collection, NULL, ob); + if (!is_link) { + BKE_collection_object_move(bmain, scene, collection, NULL, ob); } else { - BKE_collection_object_add(&scene->id, scene_collection, ob); + BKE_collection_object_add(bmain, collection, ob); } } CTX_DATA_END; @@ -1566,8 +1567,8 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) RPT_INFO, "%s %s to %s", (single_object != NULL) ? single_object->id.name + 2 : "Objects", - is_add ? "added" : "moved", - scene_collection->name); + is_link ? "linked" : "moved", + collection->id.name + 2); DEG_relations_tag_update(CTX_data_main(C)); DEG_id_tag_update(&scene->id, 0); @@ -1579,26 +1580,27 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -typedef struct MoveToCollectionData { +struct MoveToCollectionData { struct MoveToCollectionData *next, *prev; int index; - struct SceneCollection *collection; + struct Collection *collection; struct ListBase submenus; PointerRNA ptr; struct wmOperatorType *ot; -} MoveToCollectionData; +}; static int move_to_collection_menus_create(wmOperator *op, MoveToCollectionData *menu) { int index = menu->index; - for (SceneCollection *scene_collection = menu->collection->scene_collections.first; - scene_collection != NULL; - scene_collection = scene_collection->next) + for (CollectionChild *child = menu->collection->children.first; + child != NULL; + child = child->next) { + Collection *collection = child->collection; MoveToCollectionData *submenu = MEM_callocN(sizeof(MoveToCollectionData), "MoveToCollectionData submenu - expected memleak"); BLI_addtail(&menu->submenus, submenu); - submenu->collection = scene_collection; + submenu->collection = collection; submenu->index = ++index; index = move_to_collection_menus_create(op, submenu); submenu->ot = op->type; @@ -1631,11 +1633,19 @@ static void move_to_collection_menus_free(MoveToCollectionData **menu) static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout, void *menu_v) { MoveToCollectionData *menu = menu_v; + const char *name; + + if (menu->collection->flag & COLLECTION_IS_MASTER) { + name = IFACE_("Scene Collection"); + } + else { + name = menu->collection->id.name + 2; + } uiItemIntO(layout, - menu->collection->name, + name, ICON_NONE, - "OBJECT_OT_move_to_collection", + menu->ot->idname, "collection_index", menu->index); uiItemS(layout); @@ -1658,7 +1668,6 @@ static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout "New Collection", ICON_ZOOMIN, menu->ptr.data, - /* We use invoke here so we can read ctrl from event. */ WM_OP_INVOKE_DEFAULT, 0, NULL); @@ -1668,15 +1677,15 @@ static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionDat { if (BLI_listbase_is_empty(&menu->submenus)) { uiItemIntO(layout, - menu->collection->name, + menu->collection->id.name + 2, ICON_NONE, - "OBJECT_OT_move_to_collection", + menu->ot->idname, "collection_index", menu->index); } else { uiItemMenuF(layout, - menu->collection->name, + menu->collection->id.name + 2, ICON_NONE, move_to_collection_menu_create, menu); @@ -1686,8 +1695,10 @@ static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionDat /* This is allocated statically because we need this available for the menus creation callback. */ static MoveToCollectionData *master_collection_menu = NULL; -static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { + Scene *scene = CTX_data_scene(C); + /* Reset the menus data for the current master collection, and free previously allocated data. */ move_to_collection_menus_free(&master_collection_menu); @@ -1695,16 +1706,15 @@ static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent prop = RNA_struct_find_property(op->ptr, "collection_index"); if (RNA_property_is_set(op->ptr, prop)) { int collection_index = RNA_property_int_get(op->ptr, prop); - RNA_boolean_set(op->ptr, "is_add", event->ctrl); if (RNA_boolean_get(op->ptr, "is_new")) { prop = RNA_struct_find_property(op->ptr, "new_collection_name"); if (!RNA_property_is_set(op->ptr, prop)) { char name[MAX_NAME]; - SceneCollection *scene_collection; + Collection *collection; - scene_collection = BKE_collection_from_index(CTX_data_scene(C), collection_index); - BKE_collection_new_name_get(&CTX_data_scene(C)->id, scene_collection, name); + collection = BKE_collection_from_index(scene, collection_index); + BKE_collection_new_name_get(collection, name); RNA_property_string_set(op->ptr, prop, name); return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y); @@ -1713,7 +1723,7 @@ static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent return move_to_collection_exec(C, op); } - SceneCollection *master_collection = BKE_collection_master(&CTX_data_scene(C)->id); + Collection *master_collection = BKE_collection_master(scene); /* We need the data to be allocated so it's available during menu drawing. * Technically we could use wmOperator->customdata. However there is no free callback @@ -1733,10 +1743,10 @@ static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent uiLayout *layout; /* Build the menus. */ - pup = UI_popup_menu_begin(C, IFACE_("Move to Collection"), ICON_NONE); + const char *title = CTX_IFACE_(op->type->translation_context, op->type->name); + pup = UI_popup_menu_begin(C, title, ICON_NONE); layout = UI_popup_menu_layout(pup); - /* We use invoke here so we can read ctrl from event. */ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); move_to_collection_menu_create(C, layout, master_collection_menu); @@ -1752,7 +1762,7 @@ void OBJECT_OT_move_to_collection(wmOperatorType *ot) /* identifiers */ ot->name = "Move to Collection"; - ot->description = "Move to a collection only (Ctrl to add)"; + ot->description = "Move objects to a scene collection"; ot->idname = "OBJECT_OT_move_to_collection"; /* api callbacks */ @@ -1766,7 +1776,32 @@ void OBJECT_OT_move_to_collection(wmOperatorType *ot) prop = RNA_def_int(ot->srna, "collection_index", COLLECTION_INVALID_INDEX, COLLECTION_INVALID_INDEX, INT_MAX, "Collection Index", "Index of the collection to move to", 0, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); - prop = RNA_def_boolean(ot->srna, "is_add", false, "Add", "Keep object in original collections as well"); + prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); + prop = RNA_def_string(ot->srna, "new_collection_name", NULL, MAX_NAME, "Name", + "Name of the newly added collection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} + +void OBJECT_OT_link_to_collection(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Link to Collection"; + ot->description = "Link objects to a collection"; + ot->idname = "OBJECT_OT_link_to_collection"; + + /* api callbacks */ + ot->exec = move_to_collection_exec; + ot->invoke = move_to_collection_invoke; + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + prop = RNA_def_int(ot->srna, "collection_index", COLLECTION_INVALID_INDEX, COLLECTION_INVALID_INDEX, INT_MAX, + "Collection Index", "Index of the collection to move to", 0, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection"); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); |