static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) oglrender->mh->end_movie(); } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); U.obcenter_dia = oglrender->obcenter_dia_back; GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
static void rna_progress_end(struct wmWindowManager *wm) { if (wm_progress_state.is_valid) { WM_cursor_modal_restore(wm->winactive); wm_progress_state.is_valid = false; } }
static void eyedropper_exit(bContext *C, wmOperator *op) { WM_cursor_modal_restore(CTX_wm_window(C)); if (op->customdata) MEM_freeN(op->customdata); op->customdata = NULL; }
/* * Bake Dynamic Paint image sequence surface */ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) { wmWindow *win = CTX_wm_window(C); DynamicPaintModifierData *pmd = NULL; DynamicPaintCanvasSettings *canvas; Object *ob = ED_object_context(C); int status = 0; double timer = PIL_check_seconds_timer(); DynamicPaintSurface *surface; /* * Get modifier data */ pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); if (!pmd) { BKE_report(op->reports, RPT_ERROR, "Bake failed: no Dynamic Paint modifier found"); return 0; } /* Make sure we're dealing with a canvas */ canvas = pmd->canvas; if (!canvas) { BKE_report(op->reports, RPT_ERROR, "Bake failed: invalid canvas"); return 0; } surface = get_activeSurface(canvas); /* Set state to baking and init surface */ canvas->error[0] = '\0'; canvas->flags |= MOD_DPAINT_BAKING; G.is_break = false; /* reset blender_test_break*/ /* Bake Dynamic Paint */ status = dynamicPaint_bakeImageSequence(C, surface, ob); /* Clear bake */ canvas->flags &= ~MOD_DPAINT_BAKING; if (!G.background) { WM_cursor_modal_restore(win); } dynamicPaint_freeSurfaceData(surface); /* Bake was successful: * Report for ended bake and how long it took */ if (status) { /* Show bake info */ BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%.2f)", PIL_check_seconds_timer() - timer); } else { if (strlen(canvas->error)) { /* If an error occurred */ BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error); } else { /* User canceled the bake */ BKE_report(op->reports, RPT_WARNING, "Baking canceled!"); } } return status; }
static void eyedropper_colorband_exit(bContext *C, wmOperator *op) { WM_cursor_modal_restore(CTX_wm_window(C)); if (op->customdata) { EyedropperColorband *eye = op->customdata; MEM_freeN(eye->color_buffer); MEM_freeN(eye); op->customdata = NULL; } }
static void view_pan_exit(bContext *C, wmOperator *op, bool cancel) { ViewPanData *vpd = op->customdata; if (cancel) { copy_v2_v2(vpd->vec, &vpd->xorig); ED_region_tag_redraw(CTX_wm_region(C)); } WM_cursor_modal_restore(CTX_wm_window(C)); MEM_freeN(op->customdata); }
static void view_zoom_exit(bContext *C, wmOperator *op, bool cancel) { SpaceClip *sc = CTX_wm_space_clip(C); ViewZoomData *vpd = op->customdata; if (cancel) { sc->zoom = vpd->zoom; ED_region_tag_redraw(CTX_wm_region(C)); } WM_cursor_modal_restore(CTX_wm_window(C)); MEM_freeN(op->customdata); }
static int walkEnd(bContext *C, WalkInfo *walk) { wmWindow *win; RegionView3D *rv3d; if (walk->state == WALK_RUNNING) return OPERATOR_RUNNING_MODAL; #ifdef NDOF_WALK_DEBUG puts("\n-- walk end --"); #endif win = CTX_wm_window(C); rv3d = walk->rv3d; WM_event_remove_timer(CTX_wm_manager(C), win, walk->timer); ED_region_draw_cb_exit(walk->ar->type, walk->draw_handle_pixel); ED_transform_snap_object_context_destroy(walk->snap_context); ED_view3d_cameracontrol_release(walk->v3d_camera_control, walk->state == WALK_CANCEL); rv3d->rflag &= ~RV3D_NAVIGATING; if (walk->ndof) MEM_freeN(walk->ndof); /* restore the cursor */ WM_cursor_modal_restore(win); #ifdef USE_TABLET_SUPPORT if (walk->is_cursor_absolute == false) #endif { /* center the mouse */ WM_cursor_warp( win, walk->ar->winrct.xmin + walk->center_mval[0], walk->ar->winrct.ymin + walk->center_mval[1]); } if (walk->state == WALK_CONFIRM) { MEM_freeN(walk); return OPERATOR_FINISHED; } MEM_freeN(walk); return OPERATOR_CANCELLED; }
static void depthdropper_exit(bContext *C, wmOperator *op) { WM_cursor_modal_restore(CTX_wm_window(C)); if (op->customdata) { DepthDropper *ddr = (DepthDropper *)op->customdata; if (ddr->art) { ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel); } MEM_freeN(op->customdata); op->customdata = NULL; } }
/* to allow usage all over, we do entire WM */ void WM_cursor_wait(bool val) { if (!G.background) { wmWindowManager *wm = G.main->wm.first; wmWindow *win = wm ? wm->windows.first : NULL; for (; win; win = win->next) { if (val) { WM_cursor_modal_set(win, BC_WAITCURSOR); } else { WM_cursor_modal_restore(win); } } } }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; size_t i; if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) { bool do_draw = false; int exit_code = OPERATOR_RUNNING_MODAL; RulerInfo *ruler_info = op->customdata; ScrArea *sa = ruler_info->sa; ARegion *ar = ruler_info->ar; RegionView3D *rv3d = ar->regiondata; /* its possible to change spaces while running the operator [#34894] */ if (UNLIKELY(ar != CTX_wm_region(C))) { exit_code = OPERATOR_FINISHED; goto exit; } switch (event->type) { case LEFTMOUSE: if (event->val == KM_RELEASE) { if (ruler_info->state == RULER_STATE_DRAG) { /* rubber-band angle removal */ RulerItem *ruler_item = ruler_item_active_get(ruler_info); if (ruler_item && (ruler_item->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) { if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) { ruler_item->flag &= ~RULERITEM_USE_ANGLE; do_draw = true; } } if (ruler_info->snap_flag & RULER_SNAP_OK) { ruler_info->snap_flag &= ~RULER_SNAP_OK; do_draw = true; } ruler_info->state = RULER_STATE_NORMAL; } } else { if (ruler_info->state == RULER_STATE_NORMAL) { if (event->ctrl || /* weak - but user friendly */ BLI_listbase_is_empty(&ruler_info->items)) { View3D *v3d = CTX_wm_view3d(C); const bool use_depth = (v3d->drawtype >= OB_SOLID); /* Create new line */ RulerItem *ruler_item_prev = ruler_item_active_get(ruler_info); RulerItem *ruler_item; /* check if we want to drag an existing point or add a new one */ ruler_info->state = RULER_STATE_DRAG; ruler_item = ruler_item_add(ruler_info); ruler_item_active_set(ruler_info, ruler_item); if (use_depth) { /* snap the first point added, not essential but handy */ ruler_item->co_index = 0; view3d_ruler_item_mousemove(C, ruler_info, event->mval, false, true); copy_v3_v3(ruler_info->drag_start_co, ruler_item->co[ruler_item->co_index]); } else { /* initial depth either previous ruler, view offset */ if (ruler_item_prev) { copy_v3_v3(ruler_info->drag_start_co, ruler_item_prev->co[ruler_item_prev->co_index]); } else { negate_v3_v3(ruler_info->drag_start_co, rv3d->ofs); } copy_v3_v3(ruler_item->co[0], ruler_info->drag_start_co); view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval); } copy_v3_v3(ruler_item->co[2], ruler_item->co[0]); ruler_item->co_index = 2; do_draw = true; } else { float mval_fl[2] = {UNPACK2(event->mval)}; RulerItem *ruler_item_pick; int co_index; /* select and drag */ if (view3d_ruler_pick(ruler_info, mval_fl, &ruler_item_pick, &co_index)) { if (co_index == -1) { if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) { /* Add Center Point */ ruler_item_active_set(ruler_info, ruler_item_pick); ruler_item_pick->flag |= RULERITEM_USE_ANGLE; ruler_item_pick->co_index = 1; ruler_info->state = RULER_STATE_DRAG; /* find the factor */ { float co_ss[2][2]; float fac; ED_view3d_project_float_global(ar, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP); ED_view3d_project_float_global(ar, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP); fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]); CLAMP(fac, 0.0f, 1.0f); interp_v3_v3v3(ruler_item_pick->co[1], ruler_item_pick->co[0], ruler_item_pick->co[2], fac); } /* update the new location */ view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->shift != 0, event->ctrl != 0); do_draw = true; } } else { ruler_item_active_set(ruler_info, ruler_item_pick); ruler_item_pick->co_index = co_index; ruler_info->state = RULER_STATE_DRAG; /* store the initial depth */ copy_v3_v3(ruler_info->drag_start_co, ruler_item_pick->co[ruler_item_pick->co_index]); do_draw = true; } } else { exit_code = OPERATOR_PASS_THROUGH; } } } } break; case CKEY: { if (event->ctrl) { RulerItem *ruler_item = ruler_item_active_get(ruler_info); if (ruler_item) { const int prec = 8; char numstr[256]; Scene *scene = CTX_data_scene(C); UnitSettings *unit = &scene->unit; ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); WM_clipboard_text_set((void *) numstr, false); } } break; } case RIGHTCTRLKEY: case LEFTCTRLKEY: { WM_event_add_mousemove(C); break; } case MOUSEMOVE: { if (ruler_info->state == RULER_STATE_DRAG) { if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->shift != 0, event->ctrl != 0)) { do_draw = true; } } break; } case ESCKEY: { do_draw = true; exit_code = OPERATOR_CANCELLED; break; } case RETKEY: { view3d_ruler_to_gpencil(C, ruler_info); do_draw = true; exit_code = OPERATOR_FINISHED; break; } case DELKEY: { if (event->val == KM_PRESS) { if (ruler_info->state == RULER_STATE_NORMAL) { RulerItem *ruler_item = ruler_item_active_get(ruler_info); if (ruler_item) { RulerItem *ruler_item_other = ruler_item->prev ? ruler_item->prev : ruler_item->next; ruler_item_remove(ruler_info, ruler_item); ruler_item_active_set(ruler_info, ruler_item_other); do_draw = true; } } } break; } default: exit_code = OPERATOR_PASS_THROUGH; break; } if (do_draw) { view3d_ruler_header_update(sa); /* all 3d views draw rulers */ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); } exit: if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) { WM_cursor_modal_restore(ruler_info->win); view3d_ruler_end(C, ruler_info); view3d_ruler_free(ruler_info); op->customdata = NULL; ED_area_headerprint(sa, NULL); } return exit_code; }
/* common code for modal() */ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) { tPoseSlideOp *pso = op->customdata; wmWindow *win = CTX_wm_window(C); switch (event->type) { case LEFTMOUSE: /* confirm */ case RETKEY: { /* return to normal cursor and header status */ ED_area_headerprint(pso->sa, NULL); WM_cursor_modal_restore(win); /* insert keyframes as required... */ pose_slide_autoKeyframe(C, pso); pose_slide_exit(op); /* done! */ return OPERATOR_FINISHED; } case ESCKEY: /* cancel */ case RIGHTMOUSE: { /* return to normal cursor and header status */ ED_area_headerprint(pso->sa, NULL); WM_cursor_modal_restore(win); /* reset transforms back to original state */ pose_slide_reset(pso); /* depsgraph updates + redraws */ pose_slide_refresh(C, pso); /* clean up temp data */ pose_slide_exit(op); /* canceled! */ return OPERATOR_CANCELLED; } case MOUSEMOVE: /* calculate new position */ { /* calculate percentage based on position of mouse (we only use x-axis for now. * since this is more convenient for users to do), and store new percentage value */ pso->percentage = (event->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx); RNA_float_set(op->ptr, "percentage", pso->percentage); /* update percentage indicator in header */ pose_slide_draw_status(pso); /* reset transforms (to avoid accumulation errors) */ pose_slide_reset(pso); /* apply... */ pose_slide_apply(C, pso); break; } default: /* unhandled event (maybe it was some view manip? */ /* allow to pass through */ return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH; } /* still running... */ return OPERATOR_RUNNING_MODAL; }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; int i; if (oglrender->is_animation) { BLI_task_pool_work_and_wait(oglrender->task_pool); BLI_task_pool_free(oglrender->task_pool); /* Depending on various things we might or might not use global scheduler. */ if (oglrender->task_scheduler != NULL) { BLI_task_scheduler_free(oglrender->task_scheduler); } BLI_spin_end(&oglrender->reports_lock); } BLI_mutex_end(&oglrender->task_mutex); BLI_condition_end(&oglrender->task_condition); #ifdef DEBUG_TIME printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start); #endif if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); if (oglrender->is_sequencer) { MEM_freeN(oglrender->seq_data.ibufs_arr); } oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
/* common code for modal() */ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) { tPoseSlideOp *pso = op->customdata; wmWindow *win = CTX_wm_window(C); const bool has_numinput = hasNumInput(&pso->num); switch (event->type) { case LEFTMOUSE: /* confirm */ case RETKEY: case PADENTER: { /* return to normal cursor and header status */ ED_area_headerprint(pso->sa, NULL); WM_cursor_modal_restore(win); /* insert keyframes as required... */ pose_slide_autoKeyframe(C, pso); pose_slide_exit(op); /* done! */ return OPERATOR_FINISHED; } case ESCKEY: /* cancel */ case RIGHTMOUSE: { /* return to normal cursor and header status */ ED_area_headerprint(pso->sa, NULL); WM_cursor_modal_restore(win); /* reset transforms back to original state */ pose_slide_reset(pso); /* depsgraph updates + redraws */ pose_slide_refresh(C, pso); /* clean up temp data */ pose_slide_exit(op); /* canceled! */ return OPERATOR_CANCELLED; } case MOUSEMOVE: /* calculate new position */ { /* only handle mousemove if not doing numinput */ if (has_numinput == false) { /* update percentage based on position of mouse */ pose_slide_mouse_update_percentage(pso, op, event); /* update percentage indicator in header */ pose_slide_draw_status(pso); /* reset transforms (to avoid accumulation errors) */ pose_slide_reset(pso); /* apply... */ pose_slide_apply(C, pso); } break; } default: if ((event->val == KM_PRESS) && handleNumInput(C, &pso->num, event)) { float value; /* Grab percentage from numeric input, and store this new value for redo * NOTE: users see ints, while internally we use a 0-1 float */ value = pso->percentage * 100.0f; applyNumInput(&pso->num, &value); pso->percentage = value / 100.0f; CLAMP(pso->percentage, 0.0f, 1.0f); RNA_float_set(op->ptr, "percentage", pso->percentage); /* update percentage indicator in header */ pose_slide_draw_status(pso); /* reset transforms (to avoid accumulation errors) */ pose_slide_reset(pso); /* apply... */ pose_slide_apply(C, pso); break; } else { /* unhandled event - maybe it was some view manip? */ /* allow to pass through */ return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH; } } /* still running... */ return OPERATOR_RUNNING_MODAL; }