static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event) { PointerRNA ptr; PropertyRNA *prop; FileBrowseOp *fbo; char *str; if (CTX_wm_space_file(C)) { BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector, one already open"); return OPERATOR_CANCELLED; } uiFileBrowseContextProperty(C, &ptr, &prop); if (!prop) return OPERATOR_CANCELLED; str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL); /* useful yet irritating feature, Shift+Click to open the file * Alt+Click to browse a folder in the OS's browser */ if (event->shift || event->alt) { PointerRNA props_ptr; if (event->alt) { char *lslash = BLI_last_slash(str); if (lslash) *lslash = '\0'; } WM_operator_properties_create(&props_ptr, "WM_OT_path_open"); RNA_string_set(&props_ptr, "filepath", str); WM_operator_name_call(C, "WM_OT_path_open", WM_OP_EXEC_DEFAULT, &props_ptr); WM_operator_properties_free(&props_ptr); MEM_freeN(str); return OPERATOR_CANCELLED; } else { const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp"); fbo->ptr = ptr; fbo->prop = prop; op->customdata = fbo; RNA_string_set(op->ptr, path_prop, str); MEM_freeN(str); /* normally ED_fileselect_get_params would handle this but we need to because of stupid * user-prefs exception - campbell */ if (RNA_struct_find_property(op->ptr, "relative_path")) { if (!RNA_struct_property_is_set(op->ptr, "relative_path")) { /* annoying exception!, if were dealing with the user prefs, default relative to be off */ RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U)); } } WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; } }
/* only meant for timer usage */ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); ARegion *ar, *oldar = CTX_wm_region(C); int offset; int numfiles, numfiles_layout; int edit_idx = 0; int i; /* escape if not our timer */ if (sfile->smoothscroll_timer == NULL || sfile->smoothscroll_timer != event->customdata) return OPERATOR_PASS_THROUGH; numfiles = filelist_numfiles(sfile->files); /* check if we are editing a name */ for (i = 0; i < numfiles; ++i) { if (filelist_is_selected(sfile->files, i, CHECK_ALL) ) { edit_idx = i; break; } } /* if we are not editing, we are done */ if (0 == edit_idx) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } /* we need the correct area for scrolling */ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (!ar || ar->regiontype != RGN_TYPE_WINDOW) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } offset = ED_fileselect_layout_offset(sfile->layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); if (offset < 0) offset = 0; /* scroll offset is the first file in the row/column we are editing in */ if (sfile->scroll_offset == 0) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { sfile->scroll_offset = (edit_idx / sfile->layout->rows) * sfile->layout->rows; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->rows; } else { sfile->scroll_offset = (edit_idx / sfile->layout->columns) * sfile->layout->columns; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->columns; } } numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar); /* check if we have reached our final scroll position */ if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_FINISHED; } /* temporarily set context to the main window region, * so the scroll operators work */ CTX_wm_region_set(C, ar); /* scroll one step in the desired direction */ if (sfile->scroll_offset < offset) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_left", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_up", 0, NULL); } } else { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_right", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_down", 0, NULL); } } ED_region_tag_redraw(ar); /* and restore context */ CTX_wm_region_set(C, oldar); return OPERATOR_FINISHED; }
/* select strip directly under mouse */ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], short select_mode) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale = NULL; int filter; SpaceNla *snla = (SpaceNla *)ac->sl; View2D *v2d = &ac->ar->v2d; Scene *scene = ac->scene; NlaStrip *strip = NULL; int channel_index; float xmin, xmax; float x, y; /* use View2D to determine the index of the channel (i.e a row in the list) where keyframe was */ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); UI_view2d_listview_view_to_cell(v2d, 0, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index); /* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click * (that is the size of keyframe icons, so user should be expecting similar tolerances) */ xmin = UI_view2d_region_to_view_x(v2d, mval[0] - 7); xmax = UI_view2d_region_to_view_x(v2d, mval[0] + 7); /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* try to get channel */ ale = BLI_findlink(&anim_data, channel_index); if (ale == NULL) { /* channel not found */ printf("Error: animation channel (index = %d) not found in mouse_nla_strips()\n", channel_index); ANIM_animdata_freelist(&anim_data); return; } else { /* found some channel - we only really should do somethign when its an Nla-Track */ if (ale->type == ANIMTYPE_NLATRACK) { NlaTrack *nlt = (NlaTrack *)ale->data; /* loop over NLA-strips in this track, trying to find one which occurs in the necessary bounds */ for (strip = nlt->strips.first; strip; strip = strip->next) { if (BKE_nlastrip_within_bounds(strip, xmin, xmax)) break; } } /* remove active channel from list of channels for separate treatment (since it's needed later on) */ BLI_remlink(&anim_data, ale); /* free list of channels, since it's not used anymore */ ANIM_animdata_freelist(&anim_data); } /* if currently in tweakmode, exit tweakmode before changing selection states * now that we've found our target... */ if (scene->flag & SCE_NLA_EDIT_ON) WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL); /* for replacing selection, firstly need to clear existing selection */ if (select_mode == SELECT_REPLACE) { /* reset selection mode for next steps */ select_mode = SELECT_ADD; /* deselect all strips */ deselect_nla_strips(ac, 0, SELECT_SUBTRACT); /* deselect all other channels first */ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); } /* only select strip if we clicked on a valid channel and hit something */ if (ale) { /* select the strip accordingly (if a matching one was found) */ if (strip) { select_mode = selmodes_to_flagmodes(select_mode); ACHANNEL_SET_FLAG(strip, select_mode, NLASTRIP_FLAG_SELECT); /* if we selected it, we can make it active too * - we always need to clear the active strip flag though... * - as well as selecting its track... */ deselect_nla_strips(ac, DESELECT_STRIPS_CLEARACTIVE, 0); if (strip->flag & NLASTRIP_FLAG_SELECT) { strip->flag |= NLASTRIP_FLAG_ACTIVE; /* Highlight NLA-Track */ if (ale->type == ANIMTYPE_NLATRACK) { NlaTrack *nlt = (NlaTrack *)ale->data; nlt->flag |= NLATRACK_SELECTED; ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK); } } } /* free this channel */ MEM_freeN(ale); } }
void ui_but_anim_paste_driver(bContext *C) { /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL); }
void ui_but_anim_remove_keyingset(bContext *C) { /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_keyingset_button_remove", WM_OP_INVOKE_DEFAULT, NULL); }
bool WM_init_game(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; ScrArea *sa; ARegion *ar = NULL; Scene *scene = CTX_data_scene(C); if (!scene) { /* XXX, this should not be needed. */ Main *bmain = CTX_data_main(C); scene = bmain->scene.first; } win = wm->windows.first; /* first to get a valid window */ if (win) CTX_wm_window_set(C, win); sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0); ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); /* if we have a valid 3D view */ if (sa && ar) { ARegion *arhide; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* disable quad view */ if (ar->alignment == RGN_ALIGN_QSPLIT) WM_operator_name_call(C, "SCREEN_OT_region_quadview", WM_OP_EXEC_DEFAULT, NULL); /* toolbox, properties panel and header are hidden */ for (arhide = sa->regionbase.first; arhide; arhide = arhide->next) { if (arhide->regiontype != RGN_TYPE_WINDOW) { if (!(arhide->flag & RGN_FLAG_HIDDEN)) { ED_region_toggle_hidden(C, arhide); } } } /* full screen the area */ if (!sa->full) { ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* Fullscreen */ if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) { WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL); wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; } else { GHOST_RectangleHandle rect = GHOST_GetClientBounds(win->ghostwin); ar->winrct.ymax = GHOST_GetHeightRectangle(rect); ar->winrct.xmax = GHOST_GetWidthRectangle(rect); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; GHOST_DisposeRectangle(rect); } WM_operator_name_call(C, "VIEW3D_OT_game_start", WM_OP_EXEC_DEFAULT, NULL); BKE_sound_exit(); return true; } else { ReportTimerInfo *rti; BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found, game auto start is not possible"); /* After adding the report to the global list, reset the report timer. */ WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); /* Records time since last report was added */ wm->reports.reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02); rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo"); wm->reports.reporttimer->customdata = rti; return false; } }
void ui_but_anim_copy_driver(bContext *C) { /* this operator calls uiAnimContextProperty above */ WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL); }
void ui_but_anim_clear_keyframe(bContext *C) { /* this operator calls uiContextActiveProperty */ WM_operator_name_call(C, "ANIM_OT_keyframe_clear_button", WM_OP_INVOKE_DEFAULT, NULL); }
void ui_but_anim_paste_driver(bContext *C) { /* this operator calls uiContextActiveProperty */ WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL); }
static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, const wmEvent *event, const float mval[2]) { ReportList *reports = CTX_wm_reports(C); // XXX... if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) { int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; TreeStoreElem *tselem = TREESTORE(te); /* select object that's clicked on and popup context menu */ if (!(tselem->flag & TSE_SELECTED)) { if (outliner_has_one_flag(soops, &soops->tree, TSE_SELECTED, 1)) outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); tselem->flag |= TSE_SELECTED; /* redraw, same as outliner_select function */ soops->storeflag |= SO_TREESTORE_REDRAW; ED_region_tag_redraw(ar); } set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); if (scenelevel) { //if (objectlevel || datalevel || idlevel) error("Mixed selection"); //else pupmenu("Scene Operations%t|Delete"); } else if (objectlevel) { WM_operator_name_call(C, "OUTLINER_OT_object_operation", WM_OP_INVOKE_REGION_WIN, NULL); } else if (idlevel) { if (idlevel == -1 || datalevel) { BKE_report(reports, RPT_WARNING, "Mixed selection"); } else { if (idlevel == ID_GR) WM_operator_name_call(C, "OUTLINER_OT_group_operation", WM_OP_INVOKE_REGION_WIN, NULL); else WM_operator_name_call(C, "OUTLINER_OT_id_operation", WM_OP_INVOKE_REGION_WIN, NULL); } } else if (datalevel) { if (datalevel == -1) { BKE_report(reports, RPT_WARNING, "Mixed selection"); } else { if (datalevel == TSE_ANIM_DATA) WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL); else if (datalevel == TSE_DRIVER_BASE) { /* do nothing... no special ops needed yet */ } else if (ELEM(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) { /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ } else { WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); } } } return 1; } for (te = te->subtree.first; te; te = te->next) { if (do_outliner_operation_event(C, scene, ar, soops, te, event, mval)) return 1; } return 0; }
/* called by ghost, here we handle events for windows themselves or send to event system */ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr) { bContext *C = C_void_ptr; wmWindowManager *wm = CTX_wm_manager(C); GHOST_TEventType type = GHOST_GetEventType(evt); int time = GHOST_GetEventTime(evt); if (type == GHOST_kEventQuit) { WM_exit(C); } else { GHOST_WindowHandle ghostwin = GHOST_GetEventWindow(evt); GHOST_TEventDataPtr data = GHOST_GetEventData(evt); wmWindow *win; if (!ghostwin) { /* XXX - should be checked, why are we getting an event here, and */ /* what is it? */ puts("<!> event has no window"); return 1; } else if (!GHOST_ValidWindow(g_system, ghostwin)) { /* XXX - should be checked, why are we getting an event here, and */ /* what is it? */ puts("<!> event has invalid window"); return 1; } else { win = GHOST_GetWindowUserData(ghostwin); } switch (type) { case GHOST_kEventWindowDeactivate: wm_event_add_ghostevent(wm, win, type, time, data); win->active = 0; /* XXX */ break; case GHOST_kEventWindowActivate: { GHOST_TEventKeyData kdata; wmEvent event; int cx, cy, wx, wy; wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */ win->active = 1; // window_handle(win, INPUTCHANGE, win->active); /* bad ghost support for modifier keys... so on activate we set the modifiers again */ kdata.ascii = '\0'; kdata.utf8_buf[0] = '\0'; if (win->eventstate->shift && !query_qual(SHIFT)) { kdata.key = GHOST_kKeyLeftShift; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } if (win->eventstate->ctrl && !query_qual(CONTROL)) { kdata.key = GHOST_kKeyLeftControl; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } if (win->eventstate->alt && !query_qual(ALT)) { kdata.key = GHOST_kKeyLeftAlt; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } if (win->eventstate->oskey && !query_qual(OS)) { kdata.key = GHOST_kKeyOS; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } /* keymodifier zero, it hangs on hotkeys that open windows otherwise */ win->eventstate->keymodifier = 0; /* entering window, update mouse pos. but no event */ GHOST_GetCursorPosition(g_system, &wx, &wy); GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); win->eventstate->x = cx; win->eventstate->y = (win->sizey - 1) - cy; win->addmousemove = 1; /* enables highlighted buttons */ wm_window_make_drawable(C, win); /* window might be focused by mouse click in configuration of window manager * when focus is not following mouse * click could have been done on a button and depending on window manager settings * click would be passed to blender or not, but in any case button under cursor * should be activated, so at max next click on button without moving mouse * would trigger it's handle function * currently it seems to be common practice to generate new event for, but probably * we'll need utility function for this? (sergey) */ event = *(win->eventstate); event.type = MOUSEMOVE; event.prevx = event.x; event.prevy = event.y; wm_event_add(win, &event); break; } case GHOST_kEventWindowClose: { wm_window_close(C, wm, win); break; } case GHOST_kEventWindowUpdate: { if (G.debug & G_DEBUG_EVENTS) { printf("%s: ghost redraw %d\n", __func__, win->winid); } wm_window_make_drawable(C, win); WM_event_add_notifier(C, NC_WINDOW, NULL); break; } case GHOST_kEventWindowSize: case GHOST_kEventWindowMove: { GHOST_TWindowState state; state = GHOST_GetWindowState(win->ghostwin); win->windowstate = state; /* win32: gives undefined window size when minimized */ if (state != GHOST_kWindowStateMinimized) { GHOST_RectangleHandle client_rect; int l, t, r, b, scr_w, scr_h; int sizex, sizey, posx, posy; client_rect = GHOST_GetClientBounds(win->ghostwin); GHOST_GetRectangle(client_rect, &l, &t, &r, &b); GHOST_DisposeRectangle(client_rect); wm_get_screensize(&scr_w, &scr_h); sizex = r - l; sizey = b - t; posx = l; posy = scr_h - t - win->sizey; /* * Ghost sometimes send size or move events when the window hasn't changed. * One case of this is using compiz on linux. To alleviate the problem * we ignore all such event here. * * It might be good to eventually do that at Ghost level, but that is for * another time. */ if (win->sizex != sizex || win->sizey != sizey || win->posx != posx || win->posy != posy) { win->sizex = sizex; win->sizey = sizey; win->posx = posx; win->posy = posy; /* debug prints */ if (G.debug & G_DEBUG_EVENTS) { const char *state_str; state = GHOST_GetWindowState(win->ghostwin); if (state == GHOST_kWindowStateNormal) { state_str = "normal"; } else if (state == GHOST_kWindowStateMinimized) { state_str = "minimized"; } else if (state == GHOST_kWindowStateMaximized) { state_str = "maximized"; } else if (state == GHOST_kWindowStateFullScreen) { state_str = "fullscreen"; } else { state_str = "<unknown>"; } printf("%s: window %d state = %s\n", __func__, win->winid, state_str); if (type != GHOST_kEventWindowSize) { printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey); } } wm_window_make_drawable(C, win); wm_draw_window_clear(win); WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL); } } break; } case GHOST_kEventOpenMainFile: { PointerRNA props_ptr; wmWindow *oldWindow; char *path = GHOST_GetEventData(evt); if (path) { /* operator needs a valid window in context, ensures * it is correctly set */ oldWindow = CTX_wm_window(C); CTX_wm_window_set(C, win); WM_operator_properties_create(&props_ptr, "WM_OT_open_mainfile"); RNA_string_set(&props_ptr, "filepath", path); WM_operator_name_call(C, "WM_OT_open_mainfile", WM_OP_EXEC_DEFAULT, &props_ptr); WM_operator_properties_free(&props_ptr); CTX_wm_window_set(C, oldWindow); } break; } case GHOST_kEventDraggingDropDone: { wmEvent event; GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt); int cx, cy, wx, wy; /* entering window, update mouse pos */ GHOST_GetCursorPosition(g_system, &wx, &wy); GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); win->eventstate->x = cx; win->eventstate->y = (win->sizey - 1) - cy; event = *(win->eventstate); /* copy last state, like mouse coords */ /* activate region */ event.type = MOUSEMOVE; event.prevx = event.x; event.prevy = event.y; wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */ win->active = 1; wm_event_add(win, &event); /* make blender drop event with custom data pointing to wm drags */ event.type = EVT_DROP; event.val = KM_RELEASE; event.custom = EVT_DATA_LISTBASE; event.customdata = &wm->drags; event.customdatafree = 1; wm_event_add(win, &event); /* printf("Drop detected\n"); */ /* add drag data to wm for paths: */ if (ddd->dataType == GHOST_kDragnDropTypeFilenames) { GHOST_TStringArray *stra = ddd->data; int a, icon; for (a = 0; a < stra->count; a++) { printf("drop file %s\n", stra->strings[a]); /* try to get icon type from extension */ icon = ED_file_extension_icon((char *)stra->strings[a]); WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0); /* void poin should point to string, it makes a copy */ break; /* only one drop element supported now */ } } break; } default: wm_event_add_ghostevent(wm, win, type, time, data); break; } } return 1; }
static int outliner_animdata_operation_exec(bContext *C, wmOperator *op) { SpaceOops *soops = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; eOutliner_AnimDataOps event; short updateDeps = 0; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event = RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); if (datalevel != TSE_ANIM_DATA) return OPERATOR_CANCELLED; /* perform the core operation */ switch (event) { case OUTLINER_ANIMOP_CLEAR_ADT: /* Remove Animation Data - this may remove the active action, in some cases... */ outliner_do_data_operation(soops, datalevel, event, &soops->tree, clear_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Clear Animation Data"); break; case OUTLINER_ANIMOP_SET_ACT: /* delegate once again... */ WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL); break; case OUTLINER_ANIMOP_CLEAR_ACT: /* clear active action - using standard rules */ outliner_do_data_operation(soops, datalevel, event, &soops->tree, unlinkact_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Unlink action"); break; case OUTLINER_ANIMOP_REFRESH_DRV: outliner_do_data_operation(soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL); //ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */ updateDeps = 1; break; case OUTLINER_ANIMOP_CLEAR_DRV: outliner_do_data_operation(soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL); ED_undo_push(C, "Clear Drivers"); updateDeps = 1; break; default: // invalid break; } /* update dependencies */ if (updateDeps) { /* rebuild depsgraph for the new deps */ DAG_relations_tag_update(CTX_data_main(C)); } return OPERATOR_FINISHED; }
static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int extend, const float mval[2]) { if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { TreeStoreElem *tselem= TREESTORE(te); int openclose= 0; /* open close icon */ if((te->flag & TE_ICONROW)==0) { // hidden icon, no open/close if( mval[0]>te->xs && mval[0]<te->xs+UI_UNIT_X) openclose= 1; } if(openclose) { /* all below close/open? */ if(extend) { tselem->flag &= ~TSE_CLOSED; outliner_set_flag(soops, &te->subtree, TSE_CLOSED, !outliner_has_one_flag(soops, &te->subtree, TSE_CLOSED, 1)); } else { if(tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED; else tselem->flag |= TSE_CLOSED; } return 1; } /* name and first icon */ else if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) { /* always makes active object */ if(tselem->type!=TSE_SEQUENCE && tselem->type!=TSE_SEQ_STRIP && tselem->type!=TSE_SEQUENCE_DUP) tree_element_set_active_object(C, scene, soops, te, 1 + (extend!=0 && tselem->type==0)); if(tselem->type==0) { // the lib blocks /* editmode? */ if(te->idcode==ID_SCE) { if(scene!=(Scene *)tselem->id) { ED_screen_set_scene(C, (Scene *)tselem->id); } } else if(te->idcode==ID_GR) { Group *gr= (Group *)tselem->id; GroupObject *gob; if(extend) { int sel= BA_SELECT; for(gob= gr->gobject.first; gob; gob= gob->next) { if(gob->ob->flag & SELECT) { sel= BA_DESELECT; break; } } for(gob= gr->gobject.first; gob; gob= gob->next) { ED_base_object_select(object_in_scene(gob->ob, scene), sel); } } else { scene_deselect_all(scene); for(gob= gr->gobject.first; gob; gob= gob->next) { if((gob->ob->flag & SELECT) == 0) ED_base_object_select(object_in_scene(gob->ob, scene), BA_SELECT); } } WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); } else if(ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); } else { // rest of types tree_element_active(C, scene, soops, te, 1); } } else tree_element_type_active(C, scene, soops, te, tselem, 1+(extend!=0)); return 1; } } for(te= te->subtree.first; te; te= te->next) { if(do_outliner_item_activate(C, scene, ar, soops, te, extend, mval)) return 1; } return 0; }
void ui_but_anim_remove_keyingset(bContext *C) { /* this operator calls uiAnimContextProperty above */ WM_operator_name_call(C, "ANIM_OT_remove_keyingset_button", WM_OP_INVOKE_DEFAULT, NULL); }
static int edittranslation_exec(bContext *C, wmOperator *op) { uiBut *but = uiContextActiveButton(C); int ret = OPERATOR_CANCELLED; if (but) { PointerRNA ptr; char popath[FILE_MAX]; const char *root = U.i18ndir; const char *uilng = BLF_lang_get(); uiStringInfo but_label = {BUT_GET_LABEL, NULL}; uiStringInfo rna_label = {BUT_GET_RNA_LABEL, NULL}; uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; uiStringInfo but_tip = {BUT_GET_TIP, NULL}; uiStringInfo rna_tip = {BUT_GET_RNA_TIP, NULL}; uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL}; uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL}; uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, NULL}; uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, NULL}; if (!BLI_is_dir(root)) { BKE_report(op->reports, RPT_ERROR, "Please set your User Preferences' 'Translation Branches " "Directory' path to a valid directory"); return OPERATOR_CANCELLED; } if (!WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0)) { BKE_reportf(op->reports, RPT_ERROR, "Could not find operator '%s'! Please enable ui_translate addon " "in the User Preferences", EDTSRC_I18N_OP_NAME); return OPERATOR_CANCELLED; } /* Try to find a valid po file for current language... */ edittranslation_find_po_file(root, uilng, popath, FILE_MAX); /* printf("po path: %s\n", popath);*/ if (popath[0] == '\0') { BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root); return OPERATOR_CANCELLED; } uiButGetStrInfo(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip, &rna_struct, &rna_prop, &rna_enum, &rna_ctxt, NULL); WM_operator_properties_create(&ptr, EDTSRC_I18N_OP_NAME); RNA_string_set(&ptr, "lang", uilng); RNA_string_set(&ptr, "po_file", popath); RNA_string_set(&ptr, "but_label", but_label.strinfo); RNA_string_set(&ptr, "rna_label", rna_label.strinfo); RNA_string_set(&ptr, "enum_label", enum_label.strinfo); RNA_string_set(&ptr, "but_tip", but_tip.strinfo); RNA_string_set(&ptr, "rna_tip", rna_tip.strinfo); RNA_string_set(&ptr, "enum_tip", enum_tip.strinfo); RNA_string_set(&ptr, "rna_struct", rna_struct.strinfo); RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo); RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo); RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo); ret = WM_operator_name_call(C, EDTSRC_I18N_OP_NAME, WM_OP_INVOKE_DEFAULT, &ptr); /* Clean up */ if (but_label.strinfo) MEM_freeN(but_label.strinfo); if (rna_label.strinfo) MEM_freeN(rna_label.strinfo); if (enum_label.strinfo) MEM_freeN(enum_label.strinfo); if (but_tip.strinfo) MEM_freeN(but_tip.strinfo); if (rna_tip.strinfo) MEM_freeN(rna_tip.strinfo); if (enum_tip.strinfo) MEM_freeN(enum_tip.strinfo); if (rna_struct.strinfo) MEM_freeN(rna_struct.strinfo); if (rna_prop.strinfo) MEM_freeN(rna_prop.strinfo); if (rna_enum.strinfo) MEM_freeN(rna_enum.strinfo); if (rna_ctxt.strinfo) MEM_freeN(rna_ctxt.strinfo); return ret; } else { BKE_report(op->reports, RPT_ERROR, "Active button not found"); return OPERATOR_CANCELLED; } }
void ui_but_anim_remove_keyingset(bContext *C) { /* this operator calls uiContextActiveProperty */ WM_operator_name_call(C, "ANIM_OT_keyingset_button_remove", WM_OP_INVOKE_DEFAULT, NULL); }
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event) { wmWindow *win= CTX_wm_window(C); ToolSettings *ts= CTX_data_tool_settings(C); ScrArea *sa= CTX_wm_area(C); View3D *v3d= sa->spacedata.first; Object *obedit = CTX_data_edit_object(C); EditMesh *em= NULL; int ctrl= win->eventstate->ctrl, shift= win->eventstate->shift; PointerRNA props_ptr; if(obedit && obedit->type==OB_MESH) { em= BKE_mesh_get_editmesh((Mesh *)obedit->data); } /* watch it: if sa->win does not exist, check that when calling direct drawing routines */ switch(event) { case B_REDR: ED_area_tag_redraw(sa); break; case B_MODESELECT: WM_operator_properties_create(&props_ptr, "OBJECT_OT_mode_set"); RNA_enum_set(&props_ptr, "mode", v3d->modeselect); WM_operator_name_call(C, "OBJECT_OT_mode_set", WM_OP_EXEC_REGION_WIN, &props_ptr); WM_operator_properties_free(&props_ptr); break; case B_SEL_VERT: if(em) { if(shift==0 || em->selectmode==0) em->selectmode= SCE_SELECT_VERTEX; ts->selectmode= em->selectmode; EM_selectmode_set(em); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Vertex"); } break; case B_SEL_EDGE: if(em) { if(shift==0 || em->selectmode==0){ if( (em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX){ if(ctrl) EM_convertsel(em, SCE_SELECT_VERTEX,SCE_SELECT_EDGE); } em->selectmode = SCE_SELECT_EDGE; } ts->selectmode= em->selectmode; EM_selectmode_set(em); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Edge"); } break; case B_SEL_FACE: if(em) { if( shift==0 || em->selectmode==0){ if( ((em->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((em->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){ if(ctrl) EM_convertsel(em, (em->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE); } em->selectmode = SCE_SELECT_FACE; } ts->selectmode= em->selectmode; EM_selectmode_set(em); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Face"); } break; case B_MAN_TRANS: if( shift==0 || v3d->twtype==0) { v3d->twtype= V3D_MANIP_TRANSLATE; } ED_area_tag_redraw(sa); break; case B_MAN_ROT: if( shift==0 || v3d->twtype==0) { v3d->twtype= V3D_MANIP_ROTATE; } ED_area_tag_redraw(sa); break; case B_MAN_SCALE: if( shift==0 || v3d->twtype==0) { v3d->twtype= V3D_MANIP_SCALE; } ED_area_tag_redraw(sa); break; case B_NDOF: ED_area_tag_redraw(sa); break; case B_MAN_MODE: ED_area_tag_redraw(sa); break; default: break; } if(obedit && obedit->type==OB_MESH) BKE_mesh_end_editmesh(obedit->data, em); }
void ui_but_anim_insert_keyframe(bContext *C) { /* this operator calls UI_context_active_but_prop_get */ WM_operator_name_call(C, "ANIM_OT_keyframe_insert_button", WM_OP_INVOKE_DEFAULT, NULL); }
static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) { wmOperatorType *ot; int error_val = 0; PointerRNA ptr; int operator_ret = OPERATOR_CANCELLED; char *opname; char *context_str = NULL; PyObject *kw = NULL; /* optional args */ PyObject *context_dict = NULL; /* optional args */ PyObject *context_dict_back; /* note that context is an int, python does the conversion in this case */ int context = WM_OP_EXEC_DEFAULT; int is_undo = false; /* XXX Todo, work out a better solution for passing on context, * could make a tuple from self and pack the name and Context into it... */ bContext *C = (bContext *)BPy_GetContext(); if (C == NULL) { PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators"); return NULL; } if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call", &opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo)) { return NULL; } ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, "Calling operator \"bpy.ops.%s\" error, " "could not be found", opname); return NULL; } if (!pyrna_write_check()) { PyErr_Format(PyExc_RuntimeError, "Calling operator \"bpy.ops.%s\" error, " "can't modify blend data in this state (drawing/rendering)", opname); return NULL; } if (context_str) { if (RNA_enum_value_from_id(operator_context_items, context_str, &context) == 0) { char *enum_str = BPy_enum_as_string(operator_context_items); PyErr_Format(PyExc_TypeError, "Calling operator \"bpy.ops.%s\" error, " "expected a string enum in (%.200s)", opname, enum_str); MEM_freeN(enum_str); return NULL; } } if (context_dict == NULL || context_dict == Py_None) { context_dict = NULL; } else if (!PyDict_Check(context_dict)) { PyErr_Format(PyExc_TypeError, "Calling operator \"bpy.ops.%s\" error, " "custom context expected a dict or None, got a %.200s", opname, Py_TYPE(context_dict)->tp_name); return NULL; } context_dict_back = CTX_py_dict_get(C); CTX_py_dict_set(C, (void *)context_dict); Py_XINCREF(context_dict); /* so we done loose it */ if (WM_operator_poll_context((bContext *)C, ot, context) == false) { const char *msg = CTX_wm_operator_poll_msg_get(C); PyErr_Format(PyExc_RuntimeError, "Operator bpy.ops.%.200s.poll() %.200s", opname, msg ? msg : "failed, context is incorrect"); CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */ error_val = -1; } else { WM_operator_properties_create_ptr(&ptr, ot); WM_operator_properties_sanitize(&ptr, 0); if (kw && PyDict_Size(kw)) error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: "); if (error_val == 0) { ReportList *reports; reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these don't move into global reports */ #ifdef BPY_RELEASE_GIL /* release GIL, since a thread could be started from an operator * that updates a driver */ /* note: I have not seen any examples of code that does this * so it may not be officially supported but seems to work ok. */ { PyThreadState *ts = PyEval_SaveThread(); #endif operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo); #ifdef BPY_RELEASE_GIL /* regain GIL */ PyEval_RestoreThread(ts); } #endif error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false); /* operator output is nice to have in the terminal/console too */ if (reports->list.first) { char *report_str = BKE_reports_string(reports, 0); /* all reports */ if (report_str) { PySys_WriteStdout("%s\n", report_str); MEM_freeN(report_str); } } BKE_reports_clear(reports); if ((reports->flag & RPT_FREE) == 0) { MEM_freeN(reports); } } WM_operator_properties_free(&ptr); #if 0 /* if there is some way to know an operator takes args we should use this */ { /* no props */ if (kw != NULL) { PyErr_Format(PyExc_AttributeError, "Operator \"%s\" does not take any args", opname); return NULL; } WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL); } #endif } /* restore with original context dict, probably NULL but need this for nested operator calls */ Py_XDECREF(context_dict); CTX_py_dict_set(C, (void *)context_dict_back); if (error_val == -1) { return NULL; } /* when calling bpy.ops.wm.read_factory_settings() bpy.data's main pointer is freed by clear_globals(), * further access will crash blender. setting context is not needed in this case, only calling because this * function corrects bpy.data (internal Main pointer) */ BPY_modules_update(C); /* needed for when WM_OT_read_factory_settings us called from within a script */ bpy_import_main_set(CTX_data_main(C)); /* return operator_ret as a bpy enum */ return pyrna_enum_bitfield_to_py(operator_return_items, operator_ret); }
void ui_but_anim_delete_keyframe(bContext *C) { /* this operator calls uiAnimContextProperty above */ WM_operator_name_call(C, "ANIM_OT_delete_keyframe_button", WM_OP_INVOKE_DEFAULT, NULL); }