/* for effector add primitive operators */ static Object *effector_add_type(bContext *C, int type) { Scene *scene= CTX_data_scene(C); Object *ob; /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); /* freedata, and undo */ /* deselects all, sets scene->basact */ if(type==PFIELD_GUIDE) { ob = add_object(scene, OB_CURVE); ((Curve*)ob->data)->flag |= CU_PATH|CU_3D; ED_object_enter_editmode(C, 0); BLI_addtail(curve_get_editcurve(ob), add_nurbs_primitive(C, CU_NURBS|CU_PRIM_PATH, 1)); ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO); } else ob= add_object(scene, OB_EMPTY); ob->pd= object_add_collision_fields(type); /* editor level activate, notifiers */ ED_base_object_activate(C, BASACT); /* more editor stuff */ ED_object_base_init_from_view(C, BASACT); DAG_scene_sort(scene); return ob; }
/* do not call undo push in this function (users of this function have to) */ Object *ED_object_add_type(bContext *C, int type, float *loc, float *rot, int enter_editmode, unsigned int layer) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob; /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); /* freedata, and undo */ /* deselects all, sets scene->basact */ ob= add_object(scene, type); BASACT->lay = ob->lay = layer; /* editor level activate, notifiers */ ED_base_object_activate(C, BASACT); /* more editor stuff */ ED_object_base_init_transform(C, BASACT, loc, rot); DAG_scene_sort(bmain, scene); ED_render_id_flush_update(bmain, ob->data); if(enter_editmode) ED_object_enter_editmode(C, EM_IGNORE_LAYER); WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, scene); return ob; }
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; }
/* for object add primitive operators */ Object *ED_object_add_type(bContext *C, int type) { Scene *scene= CTX_data_scene(C); Object *ob; /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); /* freedata, and undo */ /* deselects all, sets scene->basact */ ob= add_object(scene, type); /* editor level activate, notifiers */ ED_base_object_activate(C, BASACT); /* more editor stuff */ ED_object_base_init_from_view(C, BASACT); DAG_scene_sort(scene); return ob; }
static int object_hide_view_set_exec(bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); short changed = 0; const int unselected= RNA_boolean_get(op->ptr, "unselected"); CTX_DATA_BEGIN(C, Base*, base, visible_bases) { if (!unselected) { if (base->flag & SELECT) { base->flag &= ~SELECT; base->object->flag = base->flag; base->object->restrictflag |= OB_RESTRICT_VIEW; changed = 1; if (base==BASACT) { ED_base_object_activate(C, NULL); } } } else { if (!(base->flag & SELECT)) { base->object->restrictflag |= OB_RESTRICT_VIEW; changed = 1; } } } CTX_DATA_END; if (changed) { DAG_id_type_tag(bmain, ID_OB); DAG_scene_sort(bmain, scene); WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); } return OPERATOR_FINISHED; }
static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool camera) { ListBase *markers = ED_context_get_markers(C); ARegion *ar = CTX_wm_region(C); View2D *v2d = UI_view2d_fromcontext(C); float viewx; int x, y, cfra; if (markers == NULL) return OPERATOR_PASS_THROUGH; x = event->x - ar->winrct.xmin; y = event->y - ar->winrct.ymin; UI_view2d_region_to_view(v2d, x, y, &viewx, NULL); cfra = ED_markers_find_nearest_marker_time(markers, viewx); if (extend) select_timeline_marker_frame(markers, cfra, 1); else select_timeline_marker_frame(markers, cfra, 0); #ifdef DURIAN_CAMERA_SWITCH if (camera) { Scene *scene = CTX_data_scene(C); Base *base; TimeMarker *marker; int sel = 0; if (!extend) BKE_scene_base_deselect_all(scene); for (marker = markers->first; marker; marker = marker->next) { if (marker->frame == cfra) { sel = (marker->flag & SELECT); break; } } for (marker = markers->first; marker; marker = marker->next) { if (marker->camera) { if (marker->frame == cfra) { base = BKE_scene_base_find(scene, marker->camera); if (base) { ED_base_object_select(base, sel); if (sel) ED_base_object_activate(C, base); } } } } WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } #else (void)camera; #endif WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL); /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails... [#25987] */ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; }
static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channel_index, short selectmode) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; View2D *v2d = &ac->ar->v2d; int notifierFlags = 0; /* get the channel that was clicked on */ /* filter channels */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* get channel from index */ ale = BLI_findlink(&anim_data, channel_index); if (ale == NULL) { /* channel not found */ if (G.debug & G_DEBUG) printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n", channel_index); ANIM_animdata_freelist(&anim_data); return 0; } /* action to take depends on what channel we've got */ // WARNING: must keep this in sync with the equivalent function in anim_channels_edit.c switch (ale->type) { case ANIMTYPE_SCENE: { Scene *sce = (Scene *)ale->data; AnimData *adt = sce->adt; /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ sce->flag ^= SCE_DS_SELECTED; if (adt) adt->flag ^= ADT_UI_SELECTED; } else { sce->flag |= SCE_DS_SELECTED; if (adt) adt->flag |= ADT_UI_SELECTED; } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); break; } case ANIMTYPE_OBJECT: { bDopeSheet *ads = (bDopeSheet *)ac->data; Scene *sce = (Scene *)ads->source; Base *base = (Base *)ale->data; Object *ob = base->object; AnimData *adt = ob->adt; if (nlaedit_is_tweakmode_on(ac) == 0) { /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ base->flag ^= SELECT; ob->flag = base->flag; if (adt) adt->flag ^= ADT_UI_SELECTED; } else { Base *b; /* deselect all */ /* TODO: should this deselect all other types of channels too? */ for (b = sce->base.first; b; b = b->next) { b->flag &= ~SELECT; b->object->flag = b->flag; if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE); } /* select object now */ base->flag |= SELECT; ob->flag |= SELECT; if (adt) adt->flag |= ADT_UI_SELECTED; } /* change active object - regardless of whether it is now selected [T37883] */ ED_base_object_activate(C, base); /* adds notifier */ if ((adt) && (adt->flag & ADT_UI_SELECTED)) adt->flag |= ADT_UI_ACTIVE; /* notifiers - channel was selected */ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); } break; } case ANIMTYPE_FILLACTD: /* Action Expander */ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ case ANIMTYPE_DSLAM: case ANIMTYPE_DSCAM: case ANIMTYPE_DSCACHEFILE: case ANIMTYPE_DSCUR: case ANIMTYPE_DSSKEY: case ANIMTYPE_DSWOR: case ANIMTYPE_DSNTREE: case ANIMTYPE_DSPART: case ANIMTYPE_DSMBALL: case ANIMTYPE_DSARM: case ANIMTYPE_DSMESH: case ANIMTYPE_DSTEX: case ANIMTYPE_DSLAT: case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: { /* sanity checking... */ if (ale->adt) { /* select/deselect */ if (selectmode == SELECT_INVERT) { /* inverse selection status of this AnimData block only */ ale->adt->flag ^= ADT_UI_SELECTED; } else { /* select AnimData block by itself */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); ale->adt->flag |= ADT_UI_SELECTED; } /* set active? */ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) ale->adt->flag |= ADT_UI_ACTIVE; } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); break; } case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; short offset; /* offset for start of channel (on LHS of channel-list) */ if (ale->id) { /* special exception for materials and particles */ if (ELEM(GS(ale->id->name), ID_MA, ID_PA)) offset = 21 + NLACHANNEL_BUTTON_WIDTH; else offset = 14; } else offset = 0; if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) { /* toggle protection (only if there's a toggle there) */ nlt->flag ^= NLATRACK_PROTECTED; /* notifier flags - channel was edited */ notifierFlags |= (ND_ANIMCHAN | NA_EDITED); } else if (x >= (v2d->cur.xmax - 2 * NLACHANNEL_BUTTON_WIDTH)) { /* toggle mute */ nlt->flag ^= NLATRACK_MUTED; /* notifier flags - channel was edited */ notifierFlags |= (ND_ANIMCHAN | NA_EDITED); } else if (x <= ((NLACHANNEL_BUTTON_WIDTH * 2) + offset)) { /* toggle 'solo' */ BKE_nlatrack_solo_toggle(adt, nlt); /* notifier flags - channel was edited */ notifierFlags |= (ND_ANIMCHAN | NA_EDITED); } else if (nlaedit_is_tweakmode_on(ac) == 0) { /* set selection */ if (selectmode == SELECT_INVERT) { /* inverse selection status of this F-Curve only */ nlt->flag ^= NLATRACK_SELECTED; } else { /* select F-Curve by itself */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); nlt->flag |= NLATRACK_SELECTED; } /* if NLA-Track is selected now, make NLA-Track the 'active' one in the visible list */ if (nlt->flag & NLATRACK_SELECTED) ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK); /* notifier flags - channel was selected */ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); } break; } case ANIMTYPE_NLAACTION: { AnimData *adt = BKE_animdata_from_id(ale->id); /* button region... */ if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) { if (nlaedit_is_tweakmode_on(ac) == 0) { /* 'push-down' action - only usable when not in TweakMode */ /* TODO: make this use the operator instead of calling the function directly * however, calling the operator requires that we supply the args, and that works with proper buttons only */ BKE_nla_action_pushdown(adt); } else { /* when in tweakmode, this button becomes the toggle for mapped editing */ adt->flag ^= ADT_NLA_EDIT_NOMAP; } /* changes to NLA-Action occurred */ notifierFlags |= ND_NLA_ACTCHANGE; } /* OR rest of name... */ else { /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block * - this is useful when there's no clear divider, and makes more sense in * the case of users trying to use this to change actions * - in tweakmode, clicking here gets us out of tweakmode, as changing selection * while in tweakmode is really evil! * - we disable "solo" flags too, to make it easier to work with stashed actions * with less trouble */ if (nlaedit_is_tweakmode_on(ac)) { /* exit tweakmode immediately */ nlaedit_disable_tweakmode(ac, true); /* changes to NLA-Action occurred */ notifierFlags |= ND_NLA_ACTCHANGE; } else { /* select/deselect */ if (selectmode == SELECT_INVERT) { /* inverse selection status of this AnimData block only */ adt->flag ^= ADT_UI_SELECTED; } else { /* select AnimData block by itself */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); adt->flag |= ADT_UI_SELECTED; } /* set active? */ if (adt->flag & ADT_UI_SELECTED) adt->flag |= ADT_UI_ACTIVE; notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); } } break; } default: if (G.debug & G_DEBUG) printf("Error: Invalid channel type in mouse_nla_channels()\n"); break; } /* free channels */ ANIM_animdata_freelist(&anim_data); /* return the notifier-flags set */ return notifierFlags; }