static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set, bool recursive) { TreeStoreElem *tselem = TREESTORE(te); Scene *sce; Base *base; Object *ob = NULL; /* if id is not object, we search back */ if (te->idcode == ID_OB) { ob = (Object *)tselem->id; } else { ob = (Object *)outliner_search_back(soops, te, ID_OB); if (ob == OBACT) return 0; } if (ob == NULL) return 0; sce = (Scene *)outliner_search_back(soops, te, ID_SCE); if (sce && scene != sce) { ED_screen_set_scene(C, CTX_wm_screen(C), sce); scene = sce; } /* find associated base in current scene */ base = BKE_scene_base_find(scene, ob); if (base) { if (set == 2) { /* swap select */ if (base->flag & SELECT) ED_base_object_select(base, BA_DESELECT); else ED_base_object_select(base, BA_SELECT); } else { /* deleselect all */ BKE_scene_base_deselect_all(scene); ED_base_object_select(base, BA_SELECT); } if (recursive) { /* Recursive select/deselect for Object hierarchies */ do_outliner_object_select_recursive(scene, ob, (ob->flag & SELECT) != 0); } if (C) { ED_base_object_activate(C, base); /* adds notifier */ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } } if (ob != scene->obedit) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); return 1; }
void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) { TreeElement *te; TreeStoreElem *tselem; for (te = lb->first; te; te = te->next) { tselem = TREESTORE(te); if (tselem->flag & TSE_SELECTED) { if (tselem->type == 0 && te->idcode == ID_OB) { // when objects selected in other scenes... dunno if that should be allowed Scene *scene_owner = (Scene *)outliner_search_back(soops, te, ID_SCE); if (scene_owner && scene_act != scene_owner) { ED_screen_set_scene(C, CTX_wm_screen(C), scene_owner); } /* important to use 'scene_owner' not scene_act else deleting objects can crash. * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the * outliner isn't showing scenes: Visible Layer draw mode for eg. */ operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem); } } if (TSELEM_OPEN(tselem, soops)) { outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb); } } }
static int tree_element_active_camera(bContext *UNUSED(C), Scene *scene, SpaceOops *soops, TreeElement *te, int set) { Object *ob= (Object *)outliner_search_back(soops, te, ID_OB); if(set) return 0; return scene->camera == ob; }
static int tree_element_active_lamp(bContext *UNUSED(C), Scene *scene, SpaceOops *soops, TreeElement *te, int set) { Object *ob; /* we search for the object parent */ ob= (Object *)outliner_search_back(soops, te, ID_OB); if(ob==NULL || ob!=OBACT) return 0; // just paranoia if(set) { // XXX extern_set_butspace(F5KEY, 0); } else return 1; return 0; }
static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) { TreeElement *tes; Object *ob; /* we search for the object parent */ ob= (Object *)outliner_search_back(soops, te, ID_OB); // note: ob->matbits can be NULL when a local object points to a library mesh. if(ob==NULL || ob!=OBACT || ob->matbits==NULL) return 0; // just paranoia /* searching in ob mat array? */ tes= te->parent; if(tes->idcode==ID_OB) { if(set) { ob->actcol= te->index+1; ob->matbits[te->index]= 1; // make ob material active too ob->colbits |= (1<<te->index); } else { if(ob->actcol == te->index+1) if(ob->matbits[te->index]) return 1; } } /* or we search for obdata material */ else { if(set) { ob->actcol= te->index+1; ob->matbits[te->index]= 0; // make obdata material active too ob->colbits &= ~(1<<te->index); } else { if(ob->actcol == te->index+1) if(ob->matbits[te->index]==0) return 1; } } if(set) { WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, NULL); } return 0; }
static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg) { bContext *C = (bContext *)Carg; Main *bmain = CTX_data_main(C); 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_MODIFIER_OP_TOGVIS) { 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_MODIFIER_OP_TOGREN) { 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_MODIFIER_OP_DELETE) { ED_object_modifier_remove(NULL, bmain, ob, md); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob); te->store_elem->flag &= ~TSE_SELECTED; } }
static void constraint_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v) { bContext *C = C_v; SpaceOops *soops = CTX_wm_space_outliner(C); bConstraint *constraint = (bConstraint *)te->directdata; Object *ob = (Object *)outliner_search_back(soops, te, ID_OB); if (event == OL_CONSTRAINTOP_ENABLE) { constraint->flag &= ~CONSTRAINT_OFF; ED_object_constraint_update(ob); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); } else if (event == OL_CONSTRAINTOP_DISABLE) { constraint->flag = CONSTRAINT_OFF; ED_object_constraint_update(ob); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); } else if (event == OL_CONSTRAINTOP_DELETE) { ListBase *lb = NULL; if (TREESTORE(te->parent->parent)->type == TSE_POSE_CHANNEL) { lb = &((bPoseChannel *)te->parent->parent->directdata)->constraints; } else { lb = &ob->constraints; } if (BKE_constraint_remove_ex(lb, ob, constraint, true)) { /* there's no active constraint now, so make sure this is the case */ BKE_constraints_active_set(&ob->constraints, NULL); ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); te->store_elem->flag &= ~TSE_SELECTED; } } }