Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * 00022 * Contributor(s): Blender Foundation, Joshua Leung 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <stdlib.h> 00033 #include <math.h> 00034 00035 #include "BLO_sys_types.h" 00036 00037 #include "BLI_utildefines.h" 00038 00039 #include "DNA_anim_types.h" 00040 #include "DNA_scene_types.h" 00041 00042 #include "BKE_context.h" 00043 #include "BKE_global.h" 00044 #include "BKE_main.h" 00045 #include "BKE_sound.h" 00046 00047 #include "UI_view2d.h" 00048 00049 #include "RNA_access.h" 00050 #include "RNA_define.h" 00051 00052 #include "WM_api.h" 00053 #include "WM_types.h" 00054 00055 #include "ED_anim_api.h" 00056 #include "ED_screen.h" 00057 00058 #include "anim_intern.h" 00059 00060 /* ********************** frame change operator ***************************/ 00061 00062 /* Check if the operator can be run from the current context */ 00063 static int change_frame_poll(bContext *C) 00064 { 00065 ScrArea *curarea= CTX_wm_area(C); 00066 00067 /* XXX temp? prevent changes during render */ 00068 if(G.rendering) return 0; 00069 00070 /* as long as there is an active area, and it isn't a Graph Editor 00071 * (since the Graph Editor has its own version which does extra stuff), 00072 * we're fine 00073 */ 00074 return ((curarea) && (curarea->spacetype != SPACE_IPO)); 00075 } 00076 00077 /* Set the new frame number */ 00078 static void change_frame_apply(bContext *C, wmOperator *op) 00079 { 00080 Main *bmain= CTX_data_main(C); 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(bmain, scene); 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 /* ************************** registration **********************************/ 00281 00282 void ED_operatortypes_anim(void) 00283 { 00284 /* Animation Editors only -------------------------- */ 00285 WM_operatortype_append(ANIM_OT_change_frame); 00286 00287 WM_operatortype_append(ANIM_OT_previewrange_set); 00288 WM_operatortype_append(ANIM_OT_previewrange_clear); 00289 00290 /* Entire UI --------------------------------------- */ 00291 WM_operatortype_append(ANIM_OT_keyframe_insert); 00292 WM_operatortype_append(ANIM_OT_keyframe_delete); 00293 WM_operatortype_append(ANIM_OT_keyframe_insert_menu); 00294 WM_operatortype_append(ANIM_OT_keyframe_delete_v3d); 00295 WM_operatortype_append(ANIM_OT_keyframe_insert_button); 00296 WM_operatortype_append(ANIM_OT_keyframe_delete_button); 00297 00298 00299 WM_operatortype_append(ANIM_OT_driver_button_add); 00300 WM_operatortype_append(ANIM_OT_driver_button_remove); 00301 WM_operatortype_append(ANIM_OT_copy_driver_button); 00302 WM_operatortype_append(ANIM_OT_paste_driver_button); 00303 00304 00305 WM_operatortype_append(ANIM_OT_keyingset_button_add); 00306 WM_operatortype_append(ANIM_OT_keyingset_button_remove); 00307 00308 WM_operatortype_append(ANIM_OT_keying_set_add); 00309 WM_operatortype_append(ANIM_OT_keying_set_remove); 00310 WM_operatortype_append(ANIM_OT_keying_set_path_add); 00311 WM_operatortype_append(ANIM_OT_keying_set_path_remove); 00312 00313 WM_operatortype_append(ANIM_OT_keying_set_active_set); 00314 } 00315 00316 void ED_keymap_anim(wmKeyConfig *keyconf) 00317 { 00318 wmKeyMap *keymap= WM_keymap_find(keyconf, "Animation", 0, 0); 00319 wmKeyMapItem *kmi; 00320 00321 /* frame management */ 00322 /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */ 00323 WM_keymap_add_item(keymap, "ANIM_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0); 00324 00325 kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TKEY, KM_PRESS, KM_CTRL, 0); 00326 RNA_string_set(kmi->ptr, "data_path", "space_data.show_seconds"); 00327 00328 /* preview range */ 00329 WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_set", PKEY, KM_PRESS, 0, 0); 00330 WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_clear", PKEY, KM_PRESS, KM_ALT, 0); 00331 }