UI: check visible layers when reading context

This resolves a problem where selected items edited for multi-value-editig
could include objects not in any visible views (unlocked layers, local view... etc).
This commit is contained in:
Campbell Barton 2015-05-13 10:56:40 +10:00
parent 08bbea9362
commit abb80abf8a
Notes: blender-bot 2023-02-14 09:07:23 +01:00
Referenced by issue #44747, Nodes: Dragging-to-toggle feature not work well sometimes
Referenced by issue #44714, crashing to desktop when switching to node editor.
3 changed files with 40 additions and 4 deletions

View File

@ -293,6 +293,8 @@ unsigned int BKE_screen_view3d_layer_active_ex(
unsigned int BKE_screen_view3d_layer_active(
const struct View3D *v3d, const struct Scene *scene) ATTR_NONNULL(2);
unsigned int BKE_screen_view3d_layer_all(const struct bScreen *sc) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene);
void BKE_screen_view3d_scene_sync(struct bScreen *sc);
void BKE_screen_view3d_main_sync(ListBase *screen_lb, struct Scene *scene);

View File

@ -518,6 +518,23 @@ unsigned int BKE_screen_view3d_layer_active(const struct View3D *v3d, const stru
return BKE_screen_view3d_layer_active_ex(v3d, scene, true);
}
/**
* Accumulate all visible layers on this screen.
*/
unsigned int BKE_screen_view3d_layer_all(const bScreen *sc)
{
const ScrArea *sa;
unsigned int lay = 0;
for (sa = sc->areabase.first; sa; sa = sa->next) {
if (sa->spacetype == SPACE_VIEW3D) {
View3D *v3d = sa->spacedata.first;
lay |= v3d->lay;
}
}
return lay;
}
void BKE_screen_view3d_sync(View3D *v3d, struct Scene *scene)
{
int bit;

View File

@ -47,6 +47,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_gpencil.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "RNA_access.h"
@ -59,6 +60,18 @@
#include "screen_intern.h"
static unsigned int context_layers(bScreen *sc, Scene *scene, ScrArea *sa_ctx)
{
/* needed for 'USE_ALLSELECT' define, otherwise we end up editing off-screen layers. */
if (sc && sa_ctx && (sa_ctx->spacetype == SPACE_BUTS)) {
const unsigned int lay = BKE_screen_view3d_layer_all(sc);
if (lay) {
return lay;
}
}
return scene->lay;
}
const char *screen_context_dir[] = {
"scene", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"selected_objects", "selected_bases",
@ -101,10 +114,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
int visible_objects = CTX_data_equals(member, "visible_objects");
for (base = scene->base.first; base; base = base->next) {
if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & scene->lay)) {
if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) {
if (visible_objects)
CTX_data_id_list_add(result, &base->object->id);
else
@ -115,10 +129,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
int selectable_objects = CTX_data_equals(member, "selectable_objects");
for (base = scene->base.first; base; base = base->next) {
if (base->lay & scene->lay) {
if (base->lay & lay) {
if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
if (selectable_objects)
CTX_data_id_list_add(result, &base->object->id);
@ -131,10 +146,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
int selected_objects = CTX_data_equals(member, "selected_objects");
for (base = scene->base.first; base; base = base->next) {
if ((base->flag & SELECT) && (base->lay & scene->lay)) {
if ((base->flag & SELECT) && (base->lay & lay)) {
if (selected_objects)
CTX_data_id_list_add(result, &base->object->id);
else
@ -145,10 +161,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
const unsigned int lay = context_layers(sc, scene, sa);
int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
for (base = scene->base.first; base; base = base->next) {
if ((base->flag & SELECT) && (base->lay & scene->lay)) {
if ((base->flag & SELECT) && (base->lay & lay)) {
if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
if (0 == BKE_object_is_libdata(base->object)) {
if (selected_editable_objects)