Cleanup: Simplify outliner context menu building queries
- Remove unnecessary calls to `get_element_operation_type()` (result wasn't used). - Remove branches/checks for cases that couldn't possibly happen. (assert instead). - Ensure all return arguments are set so caller can't make the mistake of forgetting that. - Early exit instead of big `if` block. - Use `const`.
This commit is contained in:
parent
406243c2fd
commit
8f6a38ed7e
Notes:
blender-bot
2023-02-14 01:11:05 +01:00
Referenced by issue #101007, Outliner: New context menu building design
|
@ -104,97 +104,96 @@ using blender::Vector;
|
|||
* \{ */
|
||||
|
||||
static void get_element_operation_type(
|
||||
TreeElement *te, int *scenelevel, int *objectlevel, int *idlevel, int *datalevel)
|
||||
const TreeElement *te, int *scenelevel, int *objectlevel, int *idlevel, int *datalevel)
|
||||
{
|
||||
TreeStoreElem *tselem = TREESTORE(te);
|
||||
if (tselem->flag & TSE_SELECTED) {
|
||||
/* Layer collection points to collection ID. */
|
||||
if (!ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION)) {
|
||||
if (*datalevel == 0) {
|
||||
*datalevel = tselem->type;
|
||||
}
|
||||
else if (*datalevel != tselem->type) {
|
||||
*datalevel = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const int idcode = (int)GS(tselem->id->name);
|
||||
bool is_standard_id = false;
|
||||
switch ((ID_Type)idcode) {
|
||||
case ID_SCE:
|
||||
*scenelevel = 1;
|
||||
break;
|
||||
case ID_OB:
|
||||
*objectlevel = 1;
|
||||
break;
|
||||
*scenelevel = *objectlevel = *idlevel = *datalevel = 0;
|
||||
|
||||
case ID_ME:
|
||||
case ID_CU_LEGACY:
|
||||
case ID_MB:
|
||||
case ID_LT:
|
||||
case ID_LA:
|
||||
case ID_AR:
|
||||
case ID_CA:
|
||||
case ID_SPK:
|
||||
case ID_MA:
|
||||
case ID_TE:
|
||||
case ID_IP:
|
||||
case ID_IM:
|
||||
case ID_SO:
|
||||
case ID_KE:
|
||||
case ID_WO:
|
||||
case ID_AC:
|
||||
case ID_TXT:
|
||||
case ID_GR:
|
||||
case ID_LS:
|
||||
case ID_LI:
|
||||
case ID_VF:
|
||||
case ID_NT:
|
||||
case ID_BR:
|
||||
case ID_PA:
|
||||
case ID_GD:
|
||||
case ID_MC:
|
||||
case ID_MSK:
|
||||
case ID_PAL:
|
||||
case ID_PC:
|
||||
case ID_CF:
|
||||
case ID_WS:
|
||||
case ID_LP:
|
||||
case ID_CV:
|
||||
case ID_PT:
|
||||
case ID_VO:
|
||||
case ID_SIM:
|
||||
is_standard_id = true;
|
||||
break;
|
||||
case ID_WM:
|
||||
case ID_SCR:
|
||||
/* Those are ignored here. */
|
||||
/* NOTE: while Screens should be manageable here, deleting a screen used by a workspace
|
||||
* will cause crashes when trying to use that workspace, so for now let's play minimal,
|
||||
* safe change. */
|
||||
break;
|
||||
}
|
||||
if (idcode == ID_NLA) {
|
||||
/* Fake one, not an actual ID type... */
|
||||
const TreeStoreElem *tselem = TREESTORE(te);
|
||||
if ((tselem->flag & TSE_SELECTED) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Layer collection points to collection ID. */
|
||||
if (!ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION)) {
|
||||
*datalevel = tselem->type;
|
||||
}
|
||||
else {
|
||||
const int idcode = (int)GS(tselem->id->name);
|
||||
bool is_standard_id = false;
|
||||
switch ((ID_Type)idcode) {
|
||||
case ID_SCE:
|
||||
*scenelevel = 1;
|
||||
break;
|
||||
case ID_OB:
|
||||
*objectlevel = 1;
|
||||
break;
|
||||
|
||||
case ID_ME:
|
||||
case ID_CU_LEGACY:
|
||||
case ID_MB:
|
||||
case ID_LT:
|
||||
case ID_LA:
|
||||
case ID_AR:
|
||||
case ID_CA:
|
||||
case ID_SPK:
|
||||
case ID_MA:
|
||||
case ID_TE:
|
||||
case ID_IP:
|
||||
case ID_IM:
|
||||
case ID_SO:
|
||||
case ID_KE:
|
||||
case ID_WO:
|
||||
case ID_AC:
|
||||
case ID_TXT:
|
||||
case ID_GR:
|
||||
case ID_LS:
|
||||
case ID_LI:
|
||||
case ID_VF:
|
||||
case ID_NT:
|
||||
case ID_BR:
|
||||
case ID_PA:
|
||||
case ID_GD:
|
||||
case ID_MC:
|
||||
case ID_MSK:
|
||||
case ID_PAL:
|
||||
case ID_PC:
|
||||
case ID_CF:
|
||||
case ID_WS:
|
||||
case ID_LP:
|
||||
case ID_CV:
|
||||
case ID_PT:
|
||||
case ID_VO:
|
||||
case ID_SIM:
|
||||
is_standard_id = true;
|
||||
}
|
||||
break;
|
||||
case ID_WM:
|
||||
case ID_SCR:
|
||||
/* Those are ignored here. */
|
||||
/* NOTE: while Screens should be manageable here, deleting a screen used by a workspace
|
||||
* will cause crashes when trying to use that workspace, so for now let's play minimal,
|
||||
* safe change. */
|
||||
break;
|
||||
}
|
||||
if (idcode == ID_NLA) {
|
||||
/* Fake one, not an actual ID type... */
|
||||
is_standard_id = true;
|
||||
}
|
||||
|
||||
if (is_standard_id) {
|
||||
if (*idlevel == 0) {
|
||||
*idlevel = idcode;
|
||||
}
|
||||
else if (*idlevel != idcode) {
|
||||
*idlevel = -1;
|
||||
}
|
||||
if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) {
|
||||
*datalevel = 0;
|
||||
}
|
||||
}
|
||||
if (is_standard_id) {
|
||||
*idlevel = idcode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return values are exclusive, only one may be non-null. */
|
||||
BLI_assert(((*scenelevel != 0) && (*objectlevel == 0) && (*idlevel == 0) && (*datalevel == 0)) ||
|
||||
((*scenelevel == 0) && (*objectlevel != 0) && (*idlevel == 0) && (*datalevel == 0)) ||
|
||||
((*scenelevel == 0) && (*objectlevel == 0) && (*idlevel != 0) && (*datalevel == 0)) ||
|
||||
((*scenelevel == 0) && (*objectlevel == 0) && (*idlevel == 0) && (*datalevel != 0)) ||
|
||||
/* All null. */
|
||||
((*scenelevel == 0) && (*objectlevel == 0) && (*idlevel == 0) && (*datalevel == 0)));
|
||||
}
|
||||
|
||||
static TreeElement *get_target_element(SpaceOutliner *space_outliner)
|
||||
static TreeElement *get_target_element(const SpaceOutliner *space_outliner)
|
||||
{
|
||||
TreeElement *te = outliner_find_element_with_flag(&space_outliner->tree, TSE_ACTIVE);
|
||||
|
||||
|
@ -1699,16 +1698,12 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
|
|||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
|
||||
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
|
||||
|
||||
/* check for invalid states */
|
||||
if (space_outliner == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
TreeElement *te = get_target_element(space_outliner);
|
||||
get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
|
||||
|
||||
const eOutlinerLibOpSelectionSet selection_set = static_cast<eOutlinerLibOpSelectionSet>(
|
||||
RNA_enum_get(op->ptr, "selection_set"));
|
||||
const eOutlinerLibOverrideOpTypes event = static_cast<eOutlinerLibOverrideOpTypes>(
|
||||
|
@ -2806,16 +2801,12 @@ static int outliner_lib_operation_exec(bContext *C, wmOperator *op)
|
|||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
|
||||
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
|
||||
|
||||
/* check for invalid states */
|
||||
if (space_outliner == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
TreeElement *te = get_target_element(space_outliner);
|
||||
get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
|
||||
|
||||
eOutlinerLibOpTypes event = (eOutlinerLibOpTypes)RNA_enum_get(op->ptr, "type");
|
||||
switch (event) {
|
||||
case OL_LIB_DELETE: {
|
||||
|
@ -3338,7 +3329,6 @@ static int outliner_operator_menu(bContext *C, const char *opname)
|
|||
}
|
||||
|
||||
static int do_outliner_operation_event(bContext *C,
|
||||
ReportList *reports,
|
||||
ARegion *region,
|
||||
SpaceOutliner *space_outliner,
|
||||
TreeElement *te)
|
||||
|
@ -3361,10 +3351,6 @@ static int do_outliner_operation_event(bContext *C,
|
|||
get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
|
||||
|
||||
if (scenelevel) {
|
||||
if (objectlevel || datalevel || idlevel) {
|
||||
BKE_report(reports, RPT_WARNING, "Mixed selection");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
|
||||
}
|
||||
if (objectlevel) {
|
||||
|
@ -3372,11 +3358,6 @@ static int do_outliner_operation_event(bContext *C,
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
if (idlevel) {
|
||||
if (idlevel == -1 || datalevel) {
|
||||
BKE_report(reports, RPT_WARNING, "Mixed selection");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
switch (idlevel) {
|
||||
case ID_GR:
|
||||
WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
|
||||
|
@ -3391,10 +3372,6 @@ static int do_outliner_operation_event(bContext *C,
|
|||
}
|
||||
}
|
||||
else if (datalevel) {
|
||||
if (datalevel == -1) {
|
||||
BKE_report(reports, RPT_WARNING, "Mixed selection");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (datalevel == TSE_ANIM_DATA) {
|
||||
return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
|
||||
}
|
||||
|
@ -3426,7 +3403,7 @@ static int do_outliner_operation_event(bContext *C,
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static int outliner_operation(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
|
||||
|
@ -3447,7 +3424,7 @@ static int outliner_operation(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
return do_outliner_operation_event(C, op->reports, region, space_outliner, hovered_te);
|
||||
return do_outliner_operation_event(C, region, space_outliner, hovered_te);
|
||||
}
|
||||
|
||||
void OUTLINER_OT_operation(wmOperatorType *ot)
|
||||
|
|
Loading…
Reference in New Issue