void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) { wmWindow *win; wmEventHandler *handler; char filename[FILE_MAX]; int fileflags; WM_event_remove_timer(wm, NULL, wm->autosavetimer); /* if a modal operator is running, don't autosave, but try again in 10 seconds */ for(win=wm->windows.first; win; win=win->next) { for(handler=win->modalhandlers.first; handler; handler=handler->next) { if(handler->op) { wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0); return; } } } wm_autosave_location(filename); /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_LOCK|G_FILE_SIGN); /* no error reporting to console */ BLO_write_file(CTX_data_main(C), filename, fileflags, NULL); /* do timer after file write, just in case file write takes a long time */ wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0); }
void WM_autosave_init(wmWindowManager *wm) { wm_autosave_timer_ended(wm); if (U.flag & USER_AUTOSAVE) wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0); }
int file_directory_new_exec(bContext *C, wmOperator *op) { char name[FILE_MAXFILE]; char path[FILE_MAX]; int generate_name = 1; wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); if (!sfile->params) { BKE_report(op->reports, RPT_WARNING, "No parent directory given"); return OPERATOR_CANCELLED; } path[0] = '\0'; if (RNA_struct_find_property(op->ptr, "directory")) { RNA_string_get(op->ptr, "directory", path); if (path[0] != '\0') generate_name = 0; } if (generate_name) { /* create a new, non-existing folder name */ if (!new_folder_path(sfile->params->dir, path, name)) { BKE_report(op->reports, RPT_ERROR, "Could not create new folder name"); return OPERATOR_CANCELLED; } } /* create the file */ BLI_dir_create_recursive(path); if (!BLI_exists(path)) { BKE_report(op->reports, RPT_ERROR, "Could not create new folder"); return OPERATOR_CANCELLED; } /* now remember file to jump into editing */ BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE); /* set timer to smoothly view newly generated file */ sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0); /* max 30 frs/sec */ sfile->scroll_offset = 0; /* reload dir to make sure we're seeing what's in the directory */ ED_fileselect_clear(wm, sfile); if (RNA_boolean_get(op->ptr, "open")) { BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir)); file_change_dir(C, 1); } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; }
void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(wt)) { wmWindow *win; wmEventHandler *handler; char filepath[FILE_MAX]; Scene *scene = CTX_data_scene(C); WM_event_remove_timer(wm, NULL, wm->autosavetimer); /* if a modal operator is running, don't autosave, but try again in 10 seconds */ for (win = wm->windows.first; win; win = win->next) { for (handler = win->modalhandlers.first; handler; handler = handler->next) { if (handler->op) { wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0); return; } } } if (scene) { Object *ob = OBACT; if (ob && ob->mode & OB_MODE_SCULPT) multires_force_update(ob); } wm_autosave_location(filepath); if (U.uiflag & USER_GLOBALUNDO) { /* fast save of last undobuffer, now with UI */ BKE_undo_save_file(filepath); } else { /* save as regular blend file */ int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); /* no error reporting to console */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); } /* do timer after file write, just in case file write takes a long time */ wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0); }
/* if different owner starts existing startjob, it suspends itself */ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) { if (wm_job->running) { /* signal job to end and restart */ wm_job->stop = TRUE; // printf("job started a running job, ending... %s\n", wm_job->name); } else { if (wm_job->customdata && wm_job->startjob) { wm_jobs_test_suspend_stop(wm, wm_job); if (wm_job->suspended == FALSE) { /* copy to ensure proper free in end */ wm_job->run_customdata = wm_job->customdata; wm_job->run_free = wm_job->free; wm_job->free = NULL; wm_job->customdata = NULL; wm_job->running = TRUE; if (wm_job->initjob) wm_job->initjob(wm_job->run_customdata); wm_job->stop = FALSE; wm_job->ready = FALSE; wm_job->progress = 0.0; // printf("job started: %s\n", wm_job->name); BLI_init_threads(&wm_job->threads, do_job_thread, 1); BLI_insert_thread(&wm_job->threads, wm_job); } /* restarted job has timer already */ if (wm_job->wt == NULL) wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, wm_job->timestep); if (G.debug & G_DEBUG_JOBS) wm_job->start_time = PIL_check_seconds_timer(); } else { printf("job fails, not initialized\n"); } } }
/* if different owner starts existing startjob, it suspends itself */ void WM_jobs_start(wmWindowManager *wm, wmJob *steve) { if(steve->running) { /* signal job to end and restart */ steve->stop= 1; // printf("job started a running job, ending... %s\n", steve->name); } else { if(steve->customdata && steve->startjob) { wm_jobs_test_suspend_stop(wm, steve); if(steve->suspended==0) { /* copy to ensure proper free in end */ steve->run_customdata= steve->customdata; steve->run_free= steve->free; steve->free= NULL; steve->customdata= NULL; steve->running= 1; if(steve->initjob) steve->initjob(steve->run_customdata); steve->stop= 0; steve->ready= 0; steve->progress= 0.0; // printf("job started: %s\n", steve->name); BLI_init_threads(&steve->threads, do_job_thread, 1); BLI_insert_thread(&steve->threads, steve); } /* restarted job has timer already */ if(steve->wt==NULL) steve->wt= WM_event_add_timer(wm, steve->win, TIMERJOBS, steve->timestep); } else printf("job fails, not initialized\n"); } }
static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); ViewZoomData *vpd; op->customdata = vpd = MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData"); WM_cursor_modal_set(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR); if (U.viewzoom == USER_ZOOM_CONT) { /* needs a timer to continue redrawing */ vpd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); vpd->timer_lastdraw = PIL_check_seconds_timer(); } vpd->x = event->x; vpd->y = event->y; vpd->zoom = sc->zoom; vpd->event_type = event->type; ED_clip_mouse_pos(sc, ar, event->mval, vpd->location); WM_event_add_modal_handler(C, op); }
static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEvent *event) { OGLRender *oglrender; const bool anim = RNA_boolean_get(op->ptr, "animation"); if (!screen_opengl_render_init(C, op)) return OPERATOR_CANCELLED; if (anim) { if (!screen_opengl_render_anim_initialize(C, op)) return OPERATOR_CANCELLED; } oglrender = op->customdata; render_view_open(C, event->x, event->y); /* view may be changed above (R_OUTPUT_WINDOW) */ oglrender->win = CTX_wm_window(C); WM_event_add_modal_handler(C, op); oglrender->timer = WM_event_add_timer(oglrender->wm, oglrender->win, TIMER, 0.01f); return OPERATOR_RUNNING_MODAL; }
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; } }
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) { wmWindow *win = CTX_wm_window(C); walk->rv3d = CTX_wm_region_view3d(C); walk->v3d = CTX_wm_view3d(C); walk->ar = CTX_wm_region(C); walk->scene = CTX_data_scene(C); #ifdef NDOF_WALK_DEBUG puts("\n-- walk begin --"); #endif /* sanity check: for rare but possible case (if lib-linking the camera fails) */ if ((walk->rv3d->persp == RV3D_CAMOB) && (walk->v3d->camera == NULL)) { walk->rv3d->persp = RV3D_PERSP; } if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->id.lib) { BKE_report(op->reports, RPT_ERROR, "Cannot navigate a camera from an external library"); return false; } if (ED_view3d_offset_lock_check(walk->v3d, walk->rv3d)) { BKE_report(op->reports, RPT_ERROR, "Cannot navigate when the view offset is locked"); return false; } if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->constraints.first) { BKE_report(op->reports, RPT_ERROR, "Cannot navigate an object with constraints"); return false; } walk->state = WALK_RUNNING; if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) { base_speed = U.walk_navigation.walk_speed; userdef_speed = U.walk_navigation.walk_speed; } walk->speed = 0.0f; walk->is_fast = false; walk->is_slow = false; walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ? 1.f : 1.f / walk->scene->unit.scale_length; /* user preference settings */ walk->teleport.duration = U.walk_navigation.teleport_time; walk->mouse_speed = U.walk_navigation.mouse_speed; if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY); else walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE); walk->view_height = U.walk_navigation.view_height; walk->jump_height = U.walk_navigation.jump_height; walk->speed = U.walk_navigation.walk_speed; walk->speed_factor = U.walk_navigation.walk_speed_factor; walk->gravity_state = WALK_GRAVITY_STATE_OFF; if ((walk->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)) { walk->gravity = fabsf(walk->scene->physics_settings.gravity[2]); } else { walk->gravity = 9.80668f; /* m/s2 */ } walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0); #ifdef USE_TABLET_SUPPORT walk->is_cursor_first = true; walk->is_cursor_absolute = false; #endif walk->active_directions = 0; #ifdef NDOF_WALK_DRAW_TOOMUCH walk->redraw = 1; #endif zero_v3(walk->dvec_prev); walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); walk->ndof = NULL; walk->time_lastdraw = PIL_check_seconds_timer(); walk->draw_handle_pixel = ED_region_draw_cb_activate(walk->ar->type, drawWalkPixel, walk, REGION_DRAW_POST_PIXEL); walk->rv3d->rflag |= RV3D_NAVIGATING; walk->v3d_camera_control = ED_view3d_cameracontrol_acquire( walk->scene, walk->v3d, walk->rv3d, (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); /* center the mouse */ walk->center_mval[0] = walk->ar->winx * 0.5f; walk->center_mval[1] = walk->ar->winy * 0.5f; #ifdef USE_PIXELSIZE_NATIVE_SUPPORT walk->center_mval[0] += walk->ar->winrct.xmin; walk->center_mval[1] += walk->ar->winrct.ymin; WM_cursor_compatible_xy(win, &walk->center_mval[0], &walk->center_mval[1]); walk->center_mval[0] -= walk->ar->winrct.xmin; walk->center_mval[1] -= walk->ar->winrct.ymin; #endif copy_v2_v2_int(walk->prev_mval, walk->center_mval); WM_cursor_warp(win, walk->ar->winrct.xmin + walk->center_mval[0], walk->ar->winrct.ymin + walk->center_mval[1]); /* remove the mouse cursor temporarily */ WM_cursor_modal_set(win, CURSOR_NONE); return 1; }
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); float upvec[3]; /* tmp */ float mat[3][3]; fly->rv3d = CTX_wm_region_view3d(C); fly->v3d = CTX_wm_view3d(C); fly->ar = CTX_wm_region(C); fly->scene = CTX_data_scene(C); #ifdef NDOF_FLY_DEBUG puts("\n-- fly begin --"); #endif /* sanity check: for rare but possible case (if lib-linking the camera fails) */ if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) { fly->rv3d->persp = RV3D_PERSP; } if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->id.lib) { BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); return false; } if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) { BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked"); return false; } if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) { BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints"); return false; } fly->state = FLY_RUNNING; fly->speed = 0.0f; fly->axis = 2; fly->pan_view = false; fly->xlock = FLY_AXISLOCK_STATE_OFF; fly->zlock = FLY_AXISLOCK_STATE_OFF; fly->xlock_momentum = 0.0f; fly->zlock_momentum = 0.0f; fly->grid = 1.0f; fly->use_precision = false; fly->use_freelook = false; #ifdef NDOF_FLY_DRAW_TOOMUCH fly->redraw = 1; #endif zero_v3(fly->dvec_prev); fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); copy_v2_v2_int(fly->mval, event->mval); fly->ndof = NULL; fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer(); fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL); fly->rv3d->rflag |= RV3D_NAVIGATING; /* so we draw the corner margins */ /* detect weather to start with Z locking */ upvec[0] = 1.0f; upvec[1] = 0.0f; upvec[2] = 0.0f; copy_m3_m4(mat, fly->rv3d->viewinv); mul_m3_v3(mat, upvec); if (fabsf(upvec[2]) < 0.1f) { fly->zlock = FLY_AXISLOCK_STATE_IDLE; } upvec[0] = 0; upvec[1] = 0; upvec[2] = 0; fly->persp_backup = fly->rv3d->persp; fly->dist_backup = fly->rv3d->dist; /* check for flying ortho camera - which we cant support well * we _could_ also check for an ortho camera but this is easier */ if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->rv3d->is_persp == false)) { ((Camera *)fly->v3d->camera->data)->type = CAM_PERSP; fly->is_ortho_cam = true; } if (fly->rv3d->persp == RV3D_CAMOB) { Object *ob_back; if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (fly->root_parent = fly->v3d->camera->parent)) { while (fly->root_parent->parent) fly->root_parent = fly->root_parent->parent; ob_back = fly->root_parent; } else { ob_back = fly->v3d->camera; } /* store the original camera loc and rot */ fly->obtfm = BKE_object_tfm_backup(ob_back); BKE_object_where_is_calc(fly->scene, fly->v3d->camera); negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); fly->rv3d->dist = 0.0; } else { /* perspective or ortho */ if (fly->rv3d->persp == RV3D_ORTHO) fly->rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */ copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat); copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs); /* the dist defines a vector that is infront of the offset * to rotate the view about. * this is no good for fly mode because we * want to rotate about the viewers center. * but to correct the dist removal we must * alter offset so the view doesn't jump. */ fly->rv3d->dist = 0.0f; upvec[2] = fly->dist_backup; /* x and y are 0 */ mul_m3_v3(mat, upvec); sub_v3_v3(fly->rv3d->ofs, upvec); /* Done with correcting for the dist */ } /* center the mouse, probably the UI mafia are against this but without its quite annoying */ WM_cursor_warp(win, fly->ar->winrct.xmin + fly->ar->winx / 2, fly->ar->winrct.ymin + fly->ar->winy / 2); return 1; }
/* the arguments are the desired situation */ void ED_view3d_smooth_view_ex( /* avoid passing in the context */ wmWindowManager *wm, wmWindow *win, ScrArea *sa, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, const float *ofs, const float *quat, const float *dist, const float *lens, const int smooth_viewtx) { RegionView3D *rv3d = ar->regiondata; struct SmoothView3DStore sms = {{0}}; bool ok = false; /* initialize sms */ view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d); view3d_smooth_view_state_backup(&sms.src, v3d, rv3d); /* if smoothview runs multiple times... */ if (rv3d->sms == NULL) { view3d_smooth_view_state_backup(&sms.org, v3d, rv3d); sms.org_view = rv3d->view; } else { sms.org = rv3d->sms->org; sms.org_view = rv3d->sms->org_view; } /* sms.to_camera = false; */ /* initizlized to zero anyway */ /* note on camera locking, this is a little confusing but works ok. * we may be changing the view 'as if' there is no active camera, but in fact * there is an active camera which is locked to the view. * * In the case where smooth view is moving _to_ a camera we don't want that * camera to be moved or changed, so only when the camera is not being set should * we allow camera option locking to initialize the view settings from the camera. */ if (camera == NULL && oldcamera == NULL) { ED_view3d_camera_lock_init(v3d, rv3d); } /* store the options we want to end with */ if (ofs) copy_v3_v3(sms.dst.ofs, ofs); if (quat) copy_qt_qt(sms.dst.quat, quat); if (dist) sms.dst.dist = *dist; if (lens) sms.dst.lens = *lens; if (camera) { sms.dst.dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK); ED_view3d_from_object(camera, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens); sms.to_camera = true; /* restore view3d values in end */ } /* skip smooth viewing for render engine draw */ if (smooth_viewtx && v3d->drawtype != OB_RENDER) { bool changed = false; /* zero means no difference */ if (oldcamera != camera) changed = true; else if (sms.dst.dist != rv3d->dist) changed = true; else if (sms.dst.lens != v3d->lens) changed = true; else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) changed = true; else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) changed = true; /* The new view is different from the old one * so animate the view */ if (changed) { /* original values */ if (oldcamera) { sms.src.dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f); /* this */ ED_view3d_from_object(oldcamera, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens); } /* grid draw as floor */ if ((rv3d->viewlock & RV3D_LOCKED) == 0) { /* use existing if exists, means multiple calls to smooth view wont loose the original 'view' setting */ rv3d->view = RV3D_VIEW_USER; } sms.time_allowed = (double)smooth_viewtx / 1000.0; /* if this is view rotation only * we can decrease the time allowed by * the angle between quats * this means small rotations wont lag */ if (quat && !ofs && !dist) { float vec1[3] = {0, 0, 1}, vec2[3] = {0, 0, 1}; float q1[4], q2[4]; invert_qt_qt(q1, sms.dst.quat); invert_qt_qt(q2, sms.src.quat); mul_qt_v3(q1, vec1); mul_qt_v3(q2, vec2); /* scale the time allowed by the rotation */ sms.time_allowed *= (double)angle_v3v3(vec1, vec2) / M_PI; /* 180deg == 1.0 */ } /* ensure it shows correct */ if (sms.to_camera) { /* use ortho if we move from an ortho view to an ortho camera */ rv3d->persp = (((rv3d->is_persp == false) && (camera->type == OB_CAMERA) && (((Camera *)camera->data)->type == CAM_ORTHO)) ? RV3D_ORTHO : RV3D_PERSP); } rv3d->rflag |= RV3D_NAVIGATING; /* not essential but in some cases the caller will tag the area for redraw, * and in that case we can get a flicker of the 'org' user view but we want to see 'src' */ view3d_smooth_view_state_restore(&sms.src, v3d, rv3d); /* keep track of running timer! */ if (rv3d->sms == NULL) { rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d"); } *rv3d->sms = sms; if (rv3d->smooth_timer) { WM_event_remove_timer(wm, win, rv3d->smooth_timer); } /* TIMER1 is hardcoded in keymap */ rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); /* max 30 frs/sec */ ok = true; } } /* if we get here nothing happens */ if (ok == false) { if (sms.to_camera == false) { copy_v3_v3(rv3d->ofs, sms.dst.ofs); copy_qt_qt(rv3d->viewquat, sms.dst.quat); rv3d->dist = sms.dst.dist; v3d->lens = sms.dst.lens; ED_view3d_camera_lock_sync(v3d, rv3d); } if (rv3d->viewlock & RV3D_BOXVIEW) { view3d_boxview_copy(sa, ar); } ED_region_tag_redraw(ar); } }
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); rctf viewborder; float upvec[3]; /* tmp */ float mat[3][3]; fly->rv3d = CTX_wm_region_view3d(C); fly->v3d = CTX_wm_view3d(C); fly->ar = CTX_wm_region(C); fly->scene = CTX_data_scene(C); #ifdef NDOF_FLY_DEBUG puts("\n-- fly begin --"); #endif /* sanity check: for rare but possible case (if lib-linking the camera fails) */ if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) { fly->rv3d->persp = RV3D_PERSP; } if (fly->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(fly->v3d->camera)) { BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); return false; } if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) { BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked"); return false; } if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) { BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints"); return false; } fly->state = FLY_RUNNING; fly->speed = 0.0f; fly->axis = 2; fly->pan_view = false; fly->xlock = FLY_AXISLOCK_STATE_OFF; fly->zlock = FLY_AXISLOCK_STATE_OFF; fly->xlock_momentum = 0.0f; fly->zlock_momentum = 0.0f; fly->grid = 1.0f; fly->use_precision = false; fly->use_freelook = false; #ifdef NDOF_FLY_DRAW_TOOMUCH fly->redraw = 1; #endif zero_v3(fly->dvec_prev); fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); copy_v2_v2_int(fly->mval, event->mval); #ifdef WITH_INPUT_NDOF fly->ndof = NULL; #endif fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer(); fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL); fly->rv3d->rflag |= RV3D_NAVIGATING; /* detect whether to start with Z locking */ copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); copy_m3_m4(mat, fly->rv3d->viewinv); mul_m3_v3(mat, upvec); if (fabsf(upvec[2]) < 0.1f) { fly->zlock = FLY_AXISLOCK_STATE_IDLE; } fly->v3d_camera_control = ED_view3d_cameracontrol_acquire( fly->scene, fly->v3d, fly->rv3d, (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); /* calculate center */ if (fly->scene->camera) { ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, false); fly->width = BLI_rctf_size_x(&viewborder); fly->height = BLI_rctf_size_y(&viewborder); fly->center_mval[0] = viewborder.xmin + fly->width / 2; fly->center_mval[1] = viewborder.ymin + fly->height / 2; } else { fly->width = fly->ar->winx; fly->height = fly->ar->winy; fly->center_mval[0] = fly->width / 2; fly->center_mval[1] = fly->height / 2; } /* center the mouse, probably the UI mafia are against this but without its quite annoying */ WM_cursor_warp(win, fly->ar->winrct.xmin + fly->center_mval[0], fly->ar->winrct.ymin + fly->center_mval[1]); fly_update_header(C, op, fly); return 1; }
/* XXX, need a way for python to know event types, 0x0110 is hard coded */ static wmTimer *rna_event_timer_add(struct wmWindowManager *wm, float time_step, wmWindow *win) { return WM_event_add_timer(wm, win, 0x0110, time_step); }
static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state) { uiHandlePanelData *data= pa->activedata; wmWindow *win= CTX_wm_window(C); ARegion *ar= CTX_wm_region(C); if(data && data->state == state) return; if(state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) { if(data && data->state != PANEL_STATE_ANIMATION) { /* XXX: * - the panel tabbing function call below (test_add_new_tabs()) has been commented out * "It is too easy to do by accident when reordering panels, is very hard to control and use, and has no real benefit." - BillRey * Aligorith, 2009Sep */ //test_add_new_tabs(ar); // also copies locations of tabs in dragged panel check_panel_overlap(ar, NULL); // clears } pa->flag &= ~PNL_SELECT; } else pa->flag |= PNL_SELECT; if(data && data->animtimer) { WM_event_remove_timer(CTX_wm_manager(C), win, data->animtimer); data->animtimer= NULL; } if(state == PANEL_STATE_EXIT) { MEM_freeN(data); pa->activedata= NULL; WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa); } else { if(!data) { data= MEM_callocN(sizeof(uiHandlePanelData), "uiHandlePanelData"); pa->activedata= data; WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa); } if(ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG)) data->animtimer= WM_event_add_timer(CTX_wm_manager(C), win, TIMER, ANIMATION_INTERVAL); data->state= state; data->startx= win->eventstate->x; data->starty= win->eventstate->y; data->startofsx= pa->ofsx; data->startofsy= pa->ofsy; data->startsizex= pa->sizex; data->startsizey= pa->sizey; data->starttime= PIL_check_seconds_timer(); } ED_region_tag_redraw(ar); /* XXX exception handling, 3d window preview panel */ /* if(block->drawextra==BIF_view3d_previewdraw) BIF_view3d_previewrender_clear(curarea);*/ /* XXX exception handling, 3d window preview panel */ /* if(block->drawextra==BIF_view3d_previewdraw) BIF_view3d_previewrender_signal(curarea, PR_DISPRECT); else if(strcmp(block->name, "image_panel_preview")==0) image_preview_event(2); */ }
/* the arguments are the desired situation */ void smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, float *ofs, float *quat, float *dist, float *lens) { wmWindowManager *wm= CTX_wm_manager(C); wmWindow *win= CTX_wm_window(C); ScrArea *sa= CTX_wm_area(C); RegionView3D *rv3d= ar->regiondata; struct SmoothViewStore sms= {0}; short ok= FALSE; /* initialize sms */ copy_v3_v3(sms.new_ofs, rv3d->ofs); copy_qt_qt(sms.new_quat, rv3d->viewquat); sms.new_dist= rv3d->dist; sms.new_lens= v3d->lens; sms.to_camera= 0; /* note on camera locking, this is a little confusing but works ok. * we may be changing the view 'as if' there is no active camera, but infact * there is an active camera which is locked to the view. * * In the case where smooth view is moving _to_ a camera we dont want that * camera to be moved or changed, so only when the camera is not being set should * we allow camera option locking to initialize the view settings from the camera. */ if(camera == NULL && oldcamera == NULL) { ED_view3d_camera_lock_init(v3d, rv3d); } /* store the options we want to end with */ if(ofs) copy_v3_v3(sms.new_ofs, ofs); if(quat) copy_qt_qt(sms.new_quat, quat); if(dist) sms.new_dist= *dist; if(lens) sms.new_lens= *lens; if (camera) { ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); sms.to_camera= 1; /* restore view3d values in end */ } if (C && U.smooth_viewtx) { int changed = 0; /* zero means no difference */ if (oldcamera != camera) changed = 1; else if (sms.new_dist != rv3d->dist) changed = 1; else if (sms.new_lens != v3d->lens) changed = 1; else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) changed = 1; else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) changed = 1; /* The new view is different from the old one * so animate the view */ if (changed) { /* original values */ if (oldcamera) { sms.orig_dist= rv3d->dist; // below function does weird stuff with it... ED_view3d_from_object(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens); } else { copy_v3_v3(sms.orig_ofs, rv3d->ofs); copy_qt_qt(sms.orig_quat, rv3d->viewquat); sms.orig_dist= rv3d->dist; sms.orig_lens= v3d->lens; } /* grid draw as floor */ if((rv3d->viewlock & RV3D_LOCKED)==0) { /* use existing if exists, means multiple calls to smooth view wont loose the original 'view' setting */ sms.orig_view= rv3d->sms ? rv3d->sms->orig_view : rv3d->view; rv3d->view= RV3D_VIEW_USER; } sms.time_allowed= (double)U.smooth_viewtx / 1000.0; /* if this is view rotation only * we can decrease the time allowed by * the angle between quats * this means small rotations wont lag */ if (quat && !ofs && !dist) { float vec1[3]={0,0,1}, vec2[3]= {0,0,1}; float q1[4], q2[4]; invert_qt_qt(q1, sms.new_quat); invert_qt_qt(q2, sms.orig_quat); mul_qt_v3(q1, vec1); mul_qt_v3(q2, vec2); /* scale the time allowed by the rotation */ sms.time_allowed *= (double)angle_v3v3(vec1, vec2) / M_PI; /* 180deg == 1.0 */ } /* ensure it shows correct */ if(sms.to_camera) rv3d->persp= RV3D_PERSP; rv3d->rflag |= RV3D_NAVIGATING; /* keep track of running timer! */ if(rv3d->sms==NULL) rv3d->sms= MEM_mallocN(sizeof(struct SmoothViewStore), "smoothview v3d"); *rv3d->sms= sms; if(rv3d->smooth_timer) WM_event_remove_timer(wm, win, rv3d->smooth_timer); /* TIMER1 is hardcoded in keymap */ rv3d->smooth_timer= WM_event_add_timer(wm, win, TIMER1, 1.0/100.0); /* max 30 frs/sec */ ok= TRUE; } } /* if we get here nothing happens */ if(ok == FALSE) { if(sms.to_camera==0) { copy_v3_v3(rv3d->ofs, sms.new_ofs); copy_qt_qt(rv3d->viewquat, sms.new_quat); rv3d->dist = sms.new_dist; v3d->lens = sms.new_lens; } if(rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_copy(sa, ar); ED_region_tag_redraw(ar); } }