|
Blender
V2.59
|
00001 /* 00002 * $Id: anim_ops.c 37315 2011-06-08 10:57:24Z aligorith $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation, Joshua Leung 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <stdlib.h> 00035 #include <math.h> 00036 00037 #include "BLO_sys_types.h" 00038 00039 #include "BLI_utildefines.h" 00040 00041 #include "DNA_anim_types.h" 00042 #include "DNA_scene_types.h" 00043 00044 #include "BKE_context.h" 00045 #include "BKE_global.h" 00046 #include "BKE_sound.h" 00047 00048 #include "UI_view2d.h" 00049 00050 #include "RNA_access.h" 00051 #include "RNA_define.h" 00052 00053 #include "WM_api.h" 00054 #include "WM_types.h" 00055 00056 #include "ED_anim_api.h" 00057 #include "ED_screen.h" 00058 00059 #include "anim_intern.h" 00060 00061 /* ********************** frame change operator ***************************/ 00062 00063 /* Check if the operator can be run from the current context */ 00064 static int change_frame_poll(bContext *C) 00065 { 00066 ScrArea *curarea= CTX_wm_area(C); 00067 00068 /* XXX temp? prevent changes during render */ 00069 if(G.rendering) return 0; 00070 00071 /* as long as there is an active area, and it isn't a Graph Editor 00072 * (since the Graph Editor has its own version which does extra stuff), 00073 * we're fine 00074 */ 00075 return ((curarea) && (curarea->spacetype != SPACE_IPO)); 00076 } 00077 00078 /* Set the new frame number */ 00079 static void change_frame_apply(bContext *C, wmOperator *op) 00080 { 00081 Scene *scene= CTX_data_scene(C); 00082 00083 /* set the new frame number */ 00084 CFRA= RNA_int_get(op->ptr, "frame"); 00085 FRAMENUMBER_MIN_CLAMP(CFRA); 00086 SUBFRA = 0.f; 00087 00088 /* do updates */ 00089 sound_seek_scene(C); 00090 WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); 00091 } 00092 00093 /* ---- */ 00094 00095 /* Non-modal callback for running operator without user input */ 00096 static int change_frame_exec(bContext *C, wmOperator *op) 00097 { 00098 change_frame_apply(C, op); 00099 00100 return OPERATOR_FINISHED; 00101 } 00102 00103 /* ---- */ 00104 00105 /* Get frame from mouse coordinates */ 00106 static int frame_from_event(bContext *C, wmEvent *event) 00107 { 00108 ARegion *region= CTX_wm_region(C); 00109 float viewx; 00110 00111 /* convert from region coordinates to View2D 'tot' space */ 00112 UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &viewx, NULL); 00113 00114 /* round result to nearest int (frames are ints!) */ 00115 return (int)floor(viewx+0.5f); 00116 } 00117 00118 /* Modal Operator init */ 00119 static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) 00120 { 00121 /* Change to frame that mouse is over before adding modal handler, 00122 * as user could click on a single frame (jump to frame) as well as 00123 * click-dragging over a range (modal scrubbing). 00124 */ 00125 RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); 00126 00127 change_frame_apply(C, op); 00128 00129 /* add temp handler */ 00130 WM_event_add_modal_handler(C, op); 00131 00132 return OPERATOR_RUNNING_MODAL; 00133 } 00134 00135 /* Modal event handling of frame changing */ 00136 static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event) 00137 { 00138 /* execute the events */ 00139 switch (event->type) { 00140 case ESCKEY: 00141 return OPERATOR_FINISHED; 00142 00143 case MOUSEMOVE: 00144 RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); 00145 change_frame_apply(C, op); 00146 break; 00147 00148 case LEFTMOUSE: 00149 case RIGHTMOUSE: 00150 /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init 00151 * the modal op) doesn't work for some reason 00152 */ 00153 if (event->val==KM_RELEASE) 00154 return OPERATOR_FINISHED; 00155 break; 00156 } 00157 00158 return OPERATOR_RUNNING_MODAL; 00159 } 00160 00161 static void ANIM_OT_change_frame(wmOperatorType *ot) 00162 { 00163 /* identifiers */ 00164 ot->name= "Change frame"; 00165 ot->idname= "ANIM_OT_change_frame"; 00166 ot->description= "Interactively change the current frame number"; 00167 00168 /* api callbacks */ 00169 ot->exec= change_frame_exec; 00170 ot->invoke= change_frame_invoke; 00171 ot->modal= change_frame_modal; 00172 ot->poll= change_frame_poll; 00173 00174 /* flags */ 00175 ot->flag= OPTYPE_BLOCKING|OPTYPE_UNDO; 00176 00177 /* rna */ 00178 RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); 00179 } 00180 00181 /* ****************** set preview range operator ****************************/ 00182 00183 static int previewrange_define_exec(bContext *C, wmOperator *op) 00184 { 00185 Scene *scene= CTX_data_scene(C); 00186 ARegion *ar= CTX_wm_region(C); 00187 float sfra, efra; 00188 int xmin, xmax; 00189 00190 /* get min/max values from border select rect (already in region coordinates, not screen) */ 00191 xmin= RNA_int_get(op->ptr, "xmin"); 00192 xmax= RNA_int_get(op->ptr, "xmax"); 00193 00194 /* convert min/max values to frames (i.e. region to 'tot' rect) */ 00195 UI_view2d_region_to_view(&ar->v2d, xmin, 0, &sfra, NULL); 00196 UI_view2d_region_to_view(&ar->v2d, xmax, 0, &efra, NULL); 00197 00198 /* set start/end frames for preview-range 00199 * - must clamp within allowable limits 00200 * - end must not be before start (though this won't occur most of the time) 00201 */ 00202 FRAMENUMBER_MIN_CLAMP(sfra); 00203 FRAMENUMBER_MIN_CLAMP(efra); 00204 if (efra < sfra) efra= sfra; 00205 00206 scene->r.flag |= SCER_PRV_RANGE; 00207 scene->r.psfra= (int)floor(sfra + 0.5f); 00208 scene->r.pefra= (int)floor(efra + 0.5f); 00209 00210 /* send notifiers */ 00211 WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); 00212 00213 return OPERATOR_FINISHED; 00214 } 00215 00216 static void ANIM_OT_previewrange_set(wmOperatorType *ot) 00217 { 00218 /* identifiers */ 00219 ot->name= "Set Preview Range"; 00220 ot->idname= "ANIM_OT_previewrange_set"; 00221 ot->description= "Interactively define frame range used for playback"; 00222 00223 /* api callbacks */ 00224 ot->invoke= WM_border_select_invoke; 00225 ot->exec= previewrange_define_exec; 00226 ot->modal= WM_border_select_modal; 00227 ot->cancel= WM_border_select_cancel; 00228 00229 ot->poll= ED_operator_animview_active; 00230 00231 /* flags */ 00232 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00233 00234 /* rna */ 00235 /* used to define frame range */ 00236 RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX); 00237 RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX); 00238 /* these are not used, but are needed by borderselect gesture operator stuff */ 00239 RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX); 00240 RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); 00241 } 00242 00243 /* ****************** clear preview range operator ****************************/ 00244 00245 static int previewrange_clear_exec(bContext *C, wmOperator *UNUSED(op)) 00246 { 00247 Scene *scene= CTX_data_scene(C); 00248 ScrArea *curarea= CTX_wm_area(C); 00249 00250 /* sanity checks */ 00251 if (ELEM(NULL, scene, curarea)) 00252 return OPERATOR_CANCELLED; 00253 00254 /* simply clear values */ 00255 scene->r.flag &= ~SCER_PRV_RANGE; 00256 scene->r.psfra= 0; 00257 scene->r.pefra= 0; 00258 00259 ED_area_tag_redraw(curarea); 00260 00261 return OPERATOR_FINISHED; 00262 } 00263 00264 static void ANIM_OT_previewrange_clear(wmOperatorType *ot) 00265 { 00266 /* identifiers */ 00267 ot->name= "Clear Preview Range"; 00268 ot->idname= "ANIM_OT_previewrange_clear"; 00269 ot->description= "Clear Preview Range"; 00270 00271 /* api callbacks */ 00272 ot->exec= previewrange_clear_exec; 00273 00274 ot->poll= ED_operator_animview_active; 00275 00276 /* flags */ 00277 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00278 } 00279 00280 /* ****************** time display toggle operator ****************************/ 00281 00282 static int toggle_time_exec(bContext *C, wmOperator *UNUSED(op)) 00283 { 00284 ScrArea *curarea= CTX_wm_area(C); 00285 00286 if (curarea == NULL) 00287 return OPERATOR_CANCELLED; 00288 00289 /* simply toggle draw frames flag in applicable spaces */ 00290 // XXX or should relevant spaces define their own version of this? 00291 switch (curarea->spacetype) { 00292 case SPACE_TIME: /* TimeLine */ 00293 { 00294 SpaceTime *stime= CTX_wm_space_time(C); 00295 stime->flag ^= TIME_DRAWFRAMES; 00296 } 00297 break; 00298 case SPACE_ACTION: /* Action Editor */ 00299 { 00300 SpaceAction *saction= CTX_wm_space_action(C); 00301 saction->flag ^= SACTION_DRAWTIME; 00302 } 00303 break; 00304 case SPACE_IPO: /* Graph Editor */ 00305 { 00306 SpaceIpo *sipo= CTX_wm_space_graph(C); 00307 sipo->flag ^= SIPO_DRAWTIME; 00308 } 00309 break; 00310 case SPACE_NLA: /* NLA Editor */ 00311 { 00312 SpaceNla *snla= CTX_wm_space_nla(C); 00313 snla->flag ^= SNLA_DRAWTIME; 00314 } 00315 break; 00316 case SPACE_SEQ: /* Sequencer */ 00317 { 00318 SpaceSeq *sseq= CTX_wm_space_seq(C); 00319 sseq->flag ^= SEQ_DRAWFRAMES; 00320 } 00321 break; 00322 00323 default: /* editor doesn't show frames */ 00324 return OPERATOR_CANCELLED; // XXX or should we pass through instead? 00325 } 00326 00327 ED_area_tag_redraw(curarea); 00328 00329 return OPERATOR_FINISHED; 00330 } 00331 00332 static void ANIM_OT_time_toggle(wmOperatorType *ot) 00333 { 00334 /* identifiers */ 00335 ot->name= "Toggle Frames/Seconds"; 00336 ot->idname= "ANIM_OT_time_toggle"; 00337 ot->description= "Toggle whether timing is displayed in frames or seconds for active timeline view"; 00338 00339 /* api callbacks */ 00340 ot->exec= toggle_time_exec; 00341 00342 ot->poll= ED_operator_animview_active; 00343 } 00344 00345 /* ************************** registration **********************************/ 00346 00347 void ED_operatortypes_anim(void) 00348 { 00349 /* Animation Editors only -------------------------- */ 00350 WM_operatortype_append(ANIM_OT_change_frame); 00351 WM_operatortype_append(ANIM_OT_time_toggle); 00352 00353 WM_operatortype_append(ANIM_OT_previewrange_set); 00354 WM_operatortype_append(ANIM_OT_previewrange_clear); 00355 00356 /* Entire UI --------------------------------------- */ 00357 WM_operatortype_append(ANIM_OT_keyframe_insert); 00358 WM_operatortype_append(ANIM_OT_keyframe_delete); 00359 WM_operatortype_append(ANIM_OT_keyframe_insert_menu); 00360 WM_operatortype_append(ANIM_OT_keyframe_delete_v3d); 00361 WM_operatortype_append(ANIM_OT_keyframe_insert_button); 00362 WM_operatortype_append(ANIM_OT_keyframe_delete_button); 00363 00364 00365 WM_operatortype_append(ANIM_OT_driver_button_add); 00366 WM_operatortype_append(ANIM_OT_driver_button_remove); 00367 WM_operatortype_append(ANIM_OT_copy_driver_button); 00368 WM_operatortype_append(ANIM_OT_paste_driver_button); 00369 00370 00371 WM_operatortype_append(ANIM_OT_keyingset_button_add); 00372 WM_operatortype_append(ANIM_OT_keyingset_button_remove); 00373 00374 WM_operatortype_append(ANIM_OT_keying_set_add); 00375 WM_operatortype_append(ANIM_OT_keying_set_remove); 00376 WM_operatortype_append(ANIM_OT_keying_set_path_add); 00377 WM_operatortype_append(ANIM_OT_keying_set_path_remove); 00378 00379 WM_operatortype_append(ANIM_OT_keying_set_active_set); 00380 } 00381 00382 void ED_keymap_anim(wmKeyConfig *keyconf) 00383 { 00384 wmKeyMap *keymap= WM_keymap_find(keyconf, "Animation", 0, 0); 00385 00386 /* frame management */ 00387 /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */ 00388 WM_keymap_add_item(keymap, "ANIM_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0); 00389 WM_keymap_verify_item(keymap, "ANIM_OT_time_toggle", TKEY, KM_PRESS, KM_CTRL, 0); 00390 00391 /* preview range */ 00392 WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_set", PKEY, KM_PRESS, 0, 0); 00393 WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_clear", PKEY, KM_PRESS, KM_ALT, 0); 00394 }