diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2022-07-26 00:43:48 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2022-07-26 00:43:48 +0300 |
commit | f081e76037432cb926be45e980eac201d337032c (patch) | |
tree | dd1225521c12ea21c0b0c3d51ec1ae3f8730755f /source/blender/editors/screen | |
parent | fa2084ae58a77b1201289b6bedac427f73c762d1 (diff) | |
parent | 462f99bf38648a08226b1fba423315aec2bc577b (diff) |
Merge branch 'master' into geometry-nodes-iterative-cachegeometry-nodes-rigid-body-integration
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/screen_context.c | 66 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 30 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_user_menu.c | 9 | ||||
-rw-r--r-- | source/blender/editors/screen/workspace_edit.c | 107 |
4 files changed, 173 insertions, 39 deletions
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index fe69759481b..0d6b6ee1d78 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -100,6 +100,7 @@ const char *screen_context_dir[] = { "active_gpencil_frame", "active_annotation_layer", "active_operator", + "active_action", "selected_visible_actions", "selected_editable_actions", "visible_fcurves", @@ -969,6 +970,7 @@ static eContextResult screen_ctx_active_operator(const bContext *C, bContextData } static eContextResult screen_ctx_sel_actions_impl(const bContext *C, bContextDataResult *result, + bool active_only, bool editable) { bAnimContext ac; @@ -978,11 +980,17 @@ static eContextResult screen_ctx_sel_actions_impl(const bContext *C, SpaceAction *saction = (SpaceAction *)ac.sl; if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY)) { - if (saction->action && !(editable && ID_IS_LINKED(saction->action))) { - CTX_data_id_list_add(result, &saction->action->id); + if (active_only) { + CTX_data_id_pointer_set(result, (ID *)saction->action); + } + else { + if (saction->action && !(editable && ID_IS_LINKED(saction->action))) { + CTX_data_id_list_add(result, &saction->action->id); + } + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return CTX_RESULT_OK; } } @@ -995,7 +1003,8 @@ static eContextResult screen_ctx_sel_actions_impl(const bContext *C, switch (ac.spacetype) { case SPACE_GRAPH: - filter |= ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL; + filter |= ANIMFILTER_FCURVESONLY | ANIMFILTER_CURVE_VISIBLE | + (active_only ? ANIMFILTER_ACTIVE : ANIMFILTER_SEL); break; case SPACE_ACTION: @@ -1006,7 +1015,7 @@ static eContextResult screen_ctx_sel_actions_impl(const bContext *C, ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - GSet *seen_set = BLI_gset_ptr_new("seen actions"); + GSet *seen_set = active_only ? NULL : BLI_gset_ptr_new("seen actions"); LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { /* In dopesheet check selection status of individual items, skipping @@ -1019,36 +1028,48 @@ static eContextResult screen_ctx_sel_actions_impl(const bContext *C, bAction *action = ANIM_channel_action_get(ale); if (action) { - if (editable && ID_IS_LINKED(action)) { - continue; + if (active_only) { + CTX_data_id_pointer_set(result, (ID *)action); + break; } + else { + if (editable && ID_IS_LINKED(action)) { + continue; + } - /* Add the action to the output list if not already added. */ - if (BLI_gset_add(seen_set, action)) { - CTX_data_id_list_add(result, &action->id); + /* Add the action to the output list if not already added. */ + if (BLI_gset_add(seen_set, action)) { + CTX_data_id_list_add(result, &action->id); + } } } } - BLI_gset_free(seen_set, NULL); - ANIM_animdata_freelist(&anim_data); - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + if (!active_only) { + BLI_gset_free(seen_set, NULL); + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + } + return CTX_RESULT_OK; } return CTX_RESULT_NO_DATA; } - +static eContextResult screen_ctx_active_action(const bContext *C, bContextDataResult *result) +{ + return screen_ctx_sel_actions_impl(C, result, true, false); +} static eContextResult screen_ctx_selected_visible_actions(const bContext *C, bContextDataResult *result) { - return screen_ctx_sel_actions_impl(C, result, false); + return screen_ctx_sel_actions_impl(C, result, false, false); } static eContextResult screen_ctx_selected_editable_actions(const bContext *C, bContextDataResult *result) { - return screen_ctx_sel_actions_impl(C, result, true); + return screen_ctx_sel_actions_impl(C, result, false, true); } static eContextResult screen_ctx_sel_edit_fcurves_(const bContext *C, bContextDataResult *result, @@ -1059,8 +1080,9 @@ static eContextResult screen_ctx_sel_edit_fcurves_(const bContext *C, ListBase anim_data = {NULL, NULL}; int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS) | - (ac.spacetype == SPACE_GRAPH ? ANIMFILTER_CURVE_VISIBLE : - ANIMFILTER_LIST_VISIBLE) | + (ac.spacetype == SPACE_GRAPH ? + (ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY) : + ANIMFILTER_LIST_VISIBLE) | extra_filter; ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -1104,7 +1126,7 @@ static eContextResult screen_ctx_active_editable_fcurve(const bContext *C, ListBase anim_data = {NULL, NULL}; int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT | - ANIMFILTER_CURVE_VISIBLE); + ANIMFILTER_FCURVESONLY | ANIMFILTER_CURVE_VISIBLE); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -1130,8 +1152,9 @@ static eContextResult screen_ctx_selected_editable_keyframes(const bContext *C, /* Use keyframes from editable selected FCurves. */ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS | ANIMFILTER_FOREDIT | ANIMFILTER_SEL) | - (ac.spacetype == SPACE_GRAPH ? ANIMFILTER_CURVE_VISIBLE : - ANIMFILTER_LIST_VISIBLE); + (ac.spacetype == SPACE_GRAPH ? + (ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY) : + ANIMFILTER_LIST_VISIBLE); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -1260,6 +1283,7 @@ static void ensure_ed_screen_context_functions(void) register_context_function("editable_gpencil_layers", screen_ctx_editable_gpencil_layers); register_context_function("editable_gpencil_strokes", screen_ctx_editable_gpencil_strokes); register_context_function("active_operator", screen_ctx_active_operator); + register_context_function("active_action", screen_ctx_active_action); register_context_function("selected_visible_actions", screen_ctx_selected_visible_actions); register_context_function("selected_editable_actions", screen_ctx_selected_editable_actions); register_context_function("editable_fcurves", screen_ctx_editable_fcurves); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index d35bd5ab2fe..3618b933443 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2951,9 +2951,9 @@ static int frame_offset_exec(bContext *C, wmOperator *op) int delta = RNA_int_get(op->ptr, "delta"); - CFRA += delta; - FRAMENUMBER_MIN_CLAMP(CFRA); - SUBFRA = 0.0f; + scene->r.cfra += delta; + FRAMENUMBER_MIN_CLAMP(scene->r.cfra); + scene->r.subframe = 0.0f; areas_do_frame_follow(C, false); @@ -2992,7 +2992,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); wmTimer *animtimer = CTX_wm_screen(C)->animtimer; - /* Don't change CFRA directly if animtimer is running as this can cause + /* Don't change scene->r.cfra directly if animtimer is running as this can cause * first/last frame not to be actually shown (bad since for example physics * simulations aren't reset properly). */ @@ -3010,10 +3010,10 @@ static int frame_jump_exec(bContext *C, wmOperator *op) } else { if (RNA_boolean_get(op->ptr, "end")) { - CFRA = PEFRA; + scene->r.cfra = PEFRA; } else { - CFRA = PSFRA; + scene->r.cfra = PSFRA; } areas_do_frame_follow(C, true); @@ -3062,7 +3062,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - float cfra = (float)(CFRA); + float cfra = (float)(scene->r.cfra); /* Initialize binary-tree-list for getting keyframes. */ struct AnimKeylist *keylist = ED_keylist_create(); @@ -3104,9 +3104,9 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) } while ((ak != NULL) && (done == false)) { - if (CFRA != (int)ak->cfra) { + if (scene->r.cfra != (int)ak->cfra) { /* this changes the frame, so set the frame and we're done */ - CFRA = (int)ak->cfra; + scene->r.cfra = (int)ak->cfra; done = true; } else { @@ -3165,20 +3165,20 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot) static int marker_jump_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - int closest = CFRA; + int closest = scene->r.cfra; const bool next = RNA_boolean_get(op->ptr, "next"); bool found = false; /* find matching marker in the right direction */ LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) { if (next) { - if ((marker->frame > CFRA) && (!found || closest > marker->frame)) { + if ((marker->frame > scene->r.cfra) && (!found || closest > marker->frame)) { closest = marker->frame; found = true; } } else { - if ((marker->frame < CFRA) && (!found || closest < marker->frame)) { + if ((marker->frame < scene->r.cfra) && (!found || closest < marker->frame)) { closest = marker->frame; found = true; } @@ -3192,7 +3192,7 @@ static int marker_jump_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - CFRA = closest; + scene->r.cfra = closest; areas_do_frame_follow(C, true); @@ -4714,11 +4714,11 @@ static int screen_animation_step_invoke(bContext *C, wmOperator *UNUSED(op), con if (sad->flag & ANIMPLAY_FLAG_JUMPED) { DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); #ifdef PROFILE_AUDIO_SYNCH - old_frame = CFRA; + old_frame = scene->r.cfra; #endif } - /* since we follow drawflags, we can't send notifier but tag regions ourselves */ + /* Since we follow draw-flags, we can't send notifier but tag regions ourselves. */ if (depsgraph != NULL) { ED_update_for_newframe(bmain, depsgraph); } diff --git a/source/blender/editors/screen/screen_user_menu.c b/source/blender/editors/screen/screen_user_menu.c index 1156452310c..9d66debda6f 100644 --- a/source/blender/editors/screen/screen_user_menu.c +++ b/source/blender/editors/screen/screen_user_menu.c @@ -214,7 +214,14 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu) wmOperatorType *ot = WM_operatortype_find(umi_op->op_idname, false); if (ot != NULL) { IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL; - uiItemFullO_ptr(menu->layout, ot, ui_name, ICON_NONE, prop, umi_op->opcontext, 0, NULL); + uiItemFullO_ptr(menu->layout, + ot, + CTX_IFACE_(ot->translation_context, ui_name), + ICON_NONE, + prop, + umi_op->opcontext, + 0, + NULL); is_empty = false; } else { diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 01417650b3d..cb29f15420c 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -54,17 +54,87 @@ WorkSpace *ED_workspace_add(Main *bmain, const char *name) return BKE_workspace_add(bmain, name); } +static void workspace_exit(WorkSpace *workspace, wmWindow *win) +{ + /* Scene pinning: Store whatever scene was active when leaving the workspace. It's reactivated + * when the workspace gets reactivated as well. */ + if (workspace->flags & WORKSPACE_USE_PIN_SCENE) { + workspace->pin_scene = WM_window_get_active_scene(win); + } + else { + /* The active scene may have been changed. So also always update the unpinned scene to the + * latest when leaving a workspace that has no scene pinning. */ + win->unpinned_scene = WM_window_get_active_scene(win); + } +} + +/** + * State changes (old workspace to new workspace): + * 1) unpinned -> pinned + * * Store current scene as the unpinned one (done in #workspace_exit()). + * * Change the current scene to the pinned one. + * 2) pinned -> pinned + * * Change the current scene to the new pinned one. + * 3) pinned -> unpinned + * * Change current scene back to the unpinned one + * 4) unpinned -> unpinned + * * Make sure the unpinned scene is active. + * + * Note that the pin scene must also be updated when leaving a workspace with a pinned scene. + * That's done separately via workspace_exit() above. + */ +static void workspace_scene_pinning_update(WorkSpace *workspace_new, + const WorkSpace *workspace_old, + bContext *C) +{ + wmWindow *win = CTX_wm_window(C); + Main *bmain = CTX_data_main(C); + Scene *active_scene = WM_window_get_active_scene(win); + + const bool is_new_pinned = (workspace_new->flags & WORKSPACE_USE_PIN_SCENE); + const bool is_old_pinned = (workspace_old->flags & WORKSPACE_USE_PIN_SCENE); + + /* State changes 1 and 2. */ + if (is_new_pinned) { + if (workspace_new->pin_scene && (workspace_new->pin_scene != active_scene)) { + WM_window_set_active_scene(bmain, C, win, workspace_new->pin_scene); + workspace_new->pin_scene = NULL; + } + } + /* State change 3 - Changing from workspace with pinned scene to unpinned scene. */ + else if (is_old_pinned) { + if (win->unpinned_scene) { + WM_window_set_active_scene(bmain, C, win, win->unpinned_scene); + } + else { + /* When leaving a workspace where the pinning was just enabled, the unpinned scene wasn't set + * yet. */ + win->unpinned_scene = active_scene; + } + } + else { + /* When leaving a workspace where the pinning was just disabled, we still want to restore the + * unpinned scene. */ + if (win->unpinned_scene) { + WM_window_set_active_scene(bmain, C, win, win->unpinned_scene); + } + } + + BLI_assert(WM_window_get_active_scene(win)); +} + /** * Changes the object mode (if needed) to the one set in \a workspace_new. * Object mode is still stored on object level. In future it should all be workspace level instead. */ static void workspace_change_update(WorkSpace *workspace_new, - const WorkSpace *workspace_old, + WorkSpace *workspace_old, bContext *C, wmWindowManager *wm) { + workspace_scene_pinning_update(workspace_new, workspace_old, C); /* needs to be done before changing mode! (to ensure right context) */ - UNUSED_VARS(workspace_old, workspace_new, C, wm); + UNUSED_VARS(wm); #if 0 Object *ob_act = CTX_data_active_object(C) eObjectMode mode_old = workspace_old->object_mode; eObjectMode mode_new = workspace_new->object_mode; @@ -113,6 +183,8 @@ bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager return false; } + workspace_exit(workspace_old, win); + screen_change_prepare(screen_old, screen_new, bmain, C, win); if (screen_new == NULL) { @@ -143,6 +215,7 @@ WorkSpace *ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindo WorkSpace *workspace_new = ED_workspace_add(bmain, workspace_old->id.name + 2); workspace_new->flags = workspace_old->flags; + workspace_new->pin_scene = workspace_old->pin_scene; workspace_new->object_mode = workspace_old->object_mode; workspace_new->order = workspace_old->order; BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids); @@ -512,6 +585,35 @@ static void WORKSPACE_OT_reorder_to_front(wmOperatorType *ot) ot->exec = workspace_reorder_to_front_exec; } +static int workspace_scene_pin_toggle(bContext *C, wmOperator *UNUSED(op)) +{ + WorkSpace *workspace = workspace_context_get(C); + + /* Trivial. The operator is only needed to display a superimposed extra icon, which + * requires an operator. */ + workspace->flags ^= WORKSPACE_USE_PIN_SCENE; + + WM_event_add_notifier(C, NC_WORKSPACE, NULL); + + return OPERATOR_FINISHED; +} + +static void WORKSPACE_OT_scene_pin_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Pin Scene to Workspace"; + ot->description = + "Remember the last used scene for the current workspace and switch to it whenever this " + "workspace is activated again"; + ot->idname = "WORKSPACE_OT_scene_pin_toggle"; + + /* api callbacks */ + ot->poll = workspace_context_poll; + ot->exec = workspace_scene_pin_toggle; + + ot->flag = OPTYPE_INTERNAL; +} + void ED_operatortypes_workspace(void) { WM_operatortype_append(WORKSPACE_OT_duplicate); @@ -520,6 +622,7 @@ void ED_operatortypes_workspace(void) WM_operatortype_append(WORKSPACE_OT_append_activate); WM_operatortype_append(WORKSPACE_OT_reorder_to_back); WM_operatortype_append(WORKSPACE_OT_reorder_to_front); + WM_operatortype_append(WORKSPACE_OT_scene_pin_toggle); } /** \} Workspace Operators */ |