Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_outliner/outliner_tools.c
| Context not available. | |||||
| #include "DNA_sequence_types.h" | #include "DNA_sequence_types.h" | ||||
| #include "DNA_world_types.h" | #include "DNA_world_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_constraint_types.h" | |||||
| #include "DNA_modifier_types.h" | |||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_animsys.h" | #include "BKE_animsys.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_constraint.h" | |||||
| #include "BKE_depsgraph.h" | #include "BKE_depsgraph.h" | ||||
| #include "BKE_fcurve.h" | #include "BKE_fcurve.h" | ||||
| #include "BKE_group.h" | #include "BKE_group.h" | ||||
| Context not available. | |||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_sequencer.h" | #include "BKE_sequencer.h" | ||||
| #include "BIK_api.h" | |||||
| #include "ED_armature.h" | #include "ED_armature.h" | ||||
| #include "ED_object.h" | #include "ED_object.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| Context not available. | |||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| #include "UI_resources.h" | |||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| Context not available. | |||||
| /* --------------------------------- */ | /* --------------------------------- */ | ||||
| typedef enum eOutliner_PropConstraintOps { | |||||
| OL_COP_INVALID = 0, | |||||
| OL_COP_ENABLE, | |||||
| OL_COP_DISABLE, | |||||
| OL_COP_MOVEUP, | |||||
| OL_COP_MOVEDOWN, | |||||
| OL_COP_DELETE | |||||
| } eOutliner_PropConstraintOps; | |||||
| typedef enum eOutliner_PropModifierOps { | |||||
| OL_MOP_INVALID = 0, | |||||
| OL_MOP_TOGGLEVIEWPORT, | |||||
| OL_MOP_TOGGLERENDER, | |||||
campbellbarton: remove | |||||
| OL_MOP_DELETE | |||||
| } eOutliner_PropModifierOps; | |||||
| static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg)) | static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg)) | ||||
| { | { | ||||
| bPoseChannel *pchan = (bPoseChannel *)te->directdata; | bPoseChannel *pchan = (bPoseChannel *)te->directdata; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| static void constraint_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg) | |||||
| { | |||||
| bContext *C = (bContext *)Carg; | |||||
| SpaceOops *soops = CTX_wm_space_outliner(C); | |||||
| bConstraint *constraint = (bConstraint *)te->directdata; | |||||
| Object *dropobject = (Object *)outliner_search_back(soops, te, ID_OB); | |||||
| ListBase *lb; | |||||
| if (event == OL_COP_ENABLE) { | |||||
| constraint->flag &= ~CONSTRAINT_OFF; | |||||
| } | |||||
| else if (event == OL_COP_DISABLE) { | |||||
| constraint->flag = CONSTRAINT_OFF; | |||||
| } | |||||
| else if (event == OL_COP_DELETE) { | |||||
| // code from constraint_delete_exec... | |||||
| lb = get_constraint_lb(dropobject, constraint, NULL); | |||||
| /* free the constraint */ | |||||
| if (BKE_constraint_remove(lb, constraint)) { | |||||
| /* there's no active constraint now, so make sure this is the case */ | |||||
| BKE_constraints_active_set(lb, NULL); | |||||
| ED_object_constraint_update(dropobject); /* needed to set the flags on posebones correctly */ | |||||
| /* ITASC needs to be rebuilt once a constraint is removed [#26920] */ | |||||
| if (ELEM(constraint->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK)) { | |||||
| BIK_clear_data(dropobject->pose); | |||||
campbellbartonAuthorUnsubmitted Not Done Inline ActionsThis seems very low level for outliner to worry about, I think it would be better to have some BKE API function. That this is a direct copy of object_constraint.c:1194 is a hint this could be made into an API function and shared. campbellbarton: This seems very low level for outliner to worry about, I think it would be better to have some… | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg) | |||||
| { | |||||
| bContext *C = (bContext *)Carg; | |||||
| Main *bmain = CTX_data_main(C); | |||||
Not Done Inline ActionsThis is used for the constraint UI, this comment can just be removed. campbellbarton: This is used for the constraint UI, this comment can just be removed. | |||||
| SpaceOops *soops = CTX_wm_space_outliner(C); | |||||
| ModifierData *md = (ModifierData *)te->directdata; | |||||
| Object *ob = (Object *)outliner_search_back(soops, te, ID_OB); | |||||
| if (event == OL_MOP_TOGGLEVIEWPORT) { | |||||
| md->mode ^= eModifierMode_Realtime; | |||||
| DAG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| } | |||||
| else if (event == OL_MOP_TOGGLERENDER) { | |||||
| md->mode ^= eModifierMode_Render; | |||||
| DAG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| } | |||||
| else if (event == OL_MOP_DELETE) { | |||||
| ED_object_modifier_remove(NULL, bmain, ob, md); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob); | |||||
| // TODO: this wont clear selection states (modifier below selected/deleted one appears to be selected after operation...) | |||||
| outliner_cleanup_tree(soops); | |||||
| } | |||||
| } | |||||
| static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb, | static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb, | ||||
| void (*operation_cb)(int, TreeElement *, TreeStoreElem *, void *), | void (*operation_cb)(int, TreeElement *, TreeStoreElem *, void *), | ||||
| void *arg) | void *arg) | ||||
Not Done Inline Actionsremove dead code. campbellbarton: remove dead code. | |||||
| Context not available. | |||||
| ot->prop = RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", ""); | ot->prop = RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", ""); | ||||
| } | } | ||||
| /* ******************** */ | |||||
| static EnumPropertyItem prop_constraint_op_types[] = { | |||||
| {OL_COP_ENABLE, "ENABLE", ICON_RESTRICT_VIEW_OFF, "Enable", ""}, | |||||
| {OL_COP_DISABLE, "DISABLE", ICON_RESTRICT_VIEW_ON, "Disable", ""}, | |||||
| /* TODO: needs special treatment because of multiselection */ | |||||
| //{OL_COP_MOVEUP, "MOVEUP", 0, "Move up in constraint stack", ""}, | |||||
| //{OL_COP_MOVEDOWN, "MOVEDOWN", 0, "Move down in constraint stack", ""}, | |||||
| {OL_COP_DELETE, "DELETE", ICON_X, "Delete", ""}, | |||||
| {OL_COP_INVALID, NULL, 0, NULL, NULL} | |||||
| }; | |||||
| static int outliner_constraint_operation_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| SpaceOops *soops = CTX_wm_space_outliner(C); | |||||
| int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; | |||||
| eOutliner_PropConstraintOps event; | |||||
| /* check for invalid states */ | |||||
| if (soops == NULL) | |||||
| return OPERATOR_CANCELLED; | |||||
| event = RNA_enum_get(op->ptr, "type"); | |||||
| set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); | |||||
| if (event <= 0) | |||||
| return OPERATOR_CANCELLED; | |||||
| outliner_do_data_operation(soops, datalevel, event, &soops->tree, constraint_cb, C); | |||||
| // proper updates (TODO: be more specific in 'add_notifier' and specify reference instead of NULL...) | |||||
| if (event == OL_COP_ENABLE) { | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL); | |||||
| } | |||||
| else if (event == OL_COP_DISABLE) { | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL); | |||||
| } | |||||
| else if (event == OL_COP_DELETE) { | |||||
| // apparently need to call this too... | |||||
| // TODO: this wont clear selection states (constraint below selected/deleted one appears to be selected after operation...) | |||||
| outliner_cleanup_tree(soops); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, NULL); | |||||
| } | |||||
| // not sure if we should do this? | |||||
| ED_undo_push(C, "Constraint operation"); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
Not Done Inline Actionsremoved, poll checks campbellbarton: removed, poll checks | |||||
| void OUTLINER_OT_constraint_operation(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Outliner Constraint Operation"; | |||||
| ot->idname = "OUTLINER_OT_constraint_operation"; | |||||
Not Done Inline Actionsremoved, cant happen. campbellbarton: removed, cant happen. | |||||
| ot->description = ""; | |||||
| /* callbacks */ | |||||
| ot->invoke = WM_menu_invoke; | |||||
| ot->exec = outliner_constraint_operation_exec; | |||||
| ot->poll = ED_operator_outliner_active; | |||||
| ot->flag = 0; | |||||
| ot->prop = RNA_def_enum(ot->srna, "type", prop_constraint_op_types, 0, "Constraint Operation", ""); | |||||
| } | |||||
| /* ******************** */ | /* ******************** */ | ||||
| static EnumPropertyItem prop_modifier_op_types[] = { | |||||
| {OL_MOP_TOGGLEVIEWPORT, "TOGGLEVIEWPORT", ICON_RESTRICT_VIEW_OFF, "Toggle viewport use", ""}, | |||||
campbellbartonAuthorUnsubmitted Not Done Inline ActionsNames here are a bit mixed up, but could follow - prop_object_op_types since its an internal operator. campbellbarton: Names here are a bit mixed up, but could follow - prop_object_op_types since its an internal… | |||||
| {OL_MOP_TOGGLERENDER, "TOGGLERENDER", ICON_RESTRICT_RENDER_OFF, "Toggle render use", ""}, | |||||
| {OL_MOP_DELETE, "DELETE", ICON_X, "Delete", ""}, | |||||
| {OL_MOP_INVALID, NULL, 0, NULL, NULL} | |||||
| }; | |||||
| static int outliner_modifier_operation_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| SpaceOops *soops = CTX_wm_space_outliner(C); | |||||
| int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; | |||||
| eOutliner_PropModifierOps event; | |||||
Not Done Inline Actionscan be OPERATOR_INTERNAL, since its only useful within the context of the outliner. campbellbarton: can be `OPERATOR_INTERNAL`, since its only useful within the context of the outliner. | |||||
| /* check for invalid states */ | |||||
| if (soops == NULL) | |||||
| return OPERATOR_CANCELLED; | |||||
| event = RNA_enum_get(op->ptr, "type"); | |||||
| set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); | |||||
| if (event <= 0) | |||||
| return OPERATOR_CANCELLED; | |||||
| outliner_do_data_operation(soops, datalevel, event, &soops->tree, modifier_cb, C); | |||||
| // not sure if we should do this? | |||||
| ED_undo_push(C, "Modifier operation"); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| void OUTLINER_OT_modifier_operation(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Outliner Modifier Operation"; | |||||
| ot->idname = "OUTLINER_OT_modifier_operation"; | |||||
| ot->description = ""; | |||||
| /* callbacks */ | |||||
| ot->invoke = WM_menu_invoke; | |||||
| ot->exec = outliner_modifier_operation_exec; | |||||
| ot->poll = ED_operator_outliner_active; | |||||
| ot->flag = 0; | |||||
| ot->prop = RNA_def_enum(ot->srna, "type", prop_modifier_op_types, 0, "Modifier Operation", ""); | |||||
| } | |||||
| /* ******************** */ | |||||
| static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, | static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, | ||||
| TreeElement *te, const wmEvent *event, const float mval[2]) | TreeElement *te, const wmEvent *event, const float mval[2]) | ||||
Not Done Inline ActionsCould it be more verbose? sergey: Could it be more verbose? | |||||
| Context not available. | |||||
| else if (ELEM(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) { | else if (ELEM(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) { | ||||
| /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ | /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ | ||||
| } | } | ||||
| else if (datalevel == TSE_CONSTRAINT) { | |||||
| WM_operator_name_call(C, "OUTLINER_OT_constraint_operation", WM_OP_INVOKE_REGION_WIN, NULL); | |||||
| } | |||||
| else if (datalevel == TSE_MODIFIER) { | |||||
| WM_operator_name_call(C, "OUTLINER_OT_modifier_operation", WM_OP_INVOKE_REGION_WIN, NULL); | |||||
| } | |||||
| else { | else { | ||||
| WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); | WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); | ||||
| } | } | ||||
| Context not available. | |||||
remove