Esempio n. 1
0
/* common code for invoke() methods */
static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *pso)
{
	tPChanFCurveLink *pfl;
	AnimData *adt = pso->ob->adt;
	wmWindow *win = CTX_wm_window(C);
	
	/* for each link, add all its keyframes to the search tree */
	for (pfl = pso->pfLinks.first; pfl; pfl = pfl->next) {
		LinkData *ld;
		
		/* do this for each F-Curve */
		for (ld = pfl->fcurves.first; ld; ld = ld->next) {
			FCurve *fcu = (FCurve *)ld->data;
			fcurve_to_keylist(adt, fcu, &pso->keys, NULL);
		}
	}
	
	/* consolidate these keyframes, and figure out the nearest ones */
	BLI_dlrbTree_linkedlist_sync(&pso->keys);
	
	/* cancel if no keyframes found... */
	if (pso->keys.root) {
		ActKeyColumn *ak;
		float cframe = (float)pso->cframe;
		
		/* firstly, check if the current frame is a keyframe... */
		ak = (ActKeyColumn *)BLI_dlrbTree_search_exact(&pso->keys, compare_ak_cfraPtr, &cframe);
		
		if (ak == NULL) {
			/* current frame is not a keyframe, so search */
			ActKeyColumn *pk = (ActKeyColumn *)BLI_dlrbTree_search_prev(&pso->keys, compare_ak_cfraPtr, &cframe);
			ActKeyColumn *nk = (ActKeyColumn *)BLI_dlrbTree_search_next(&pso->keys, compare_ak_cfraPtr, &cframe);
			
			/* new set the frames */
			/* prev frame */
			pso->prevFrame = (pk) ? (pk->cfra) : (pso->cframe - 1);
			RNA_int_set(op->ptr, "prev_frame", pso->prevFrame);
			/* next frame */
			pso->nextFrame = (nk) ? (nk->cfra) : (pso->cframe + 1);
			RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
		}
		else {
			/* current frame itself is a keyframe, so just take keyframes on either side */
			/* prev frame */
			pso->prevFrame = (ak->prev) ? (ak->prev->cfra) : (pso->cframe - 1);
			RNA_int_set(op->ptr, "prev_frame", pso->prevFrame);
			/* next frame */
			pso->nextFrame = (ak->next) ? (ak->next->cfra) : (pso->cframe + 1);
			RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
		}
	}
	else {
		BKE_report(op->reports, RPT_ERROR, "No keyframes to slide between");
		pose_slide_exit(op);
		return OPERATOR_CANCELLED;
	}
	
	/* initial apply for operator... */
	/* TODO: need to calculate percentage for initial round too... */
	pose_slide_apply(C, pso);
	
	/* depsgraph updates + redraws */
	pose_slide_refresh(C, pso);
	
	/* set cursor to indicate modal */
	WM_cursor_modal_set(win, BC_EW_SCROLLCURSOR);
	
	/* header print */
	pose_slide_draw_status(pso);
	
	/* add a modal handler for this operator */
	WM_event_add_modal_handler(C, op);
	return OPERATOR_RUNNING_MODAL;
}
Esempio n. 2
0
/* 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;
}
Esempio n. 3
0
/* 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;
}