acf9d392ed4e24b3de6c1d89e1a13879e723871e
[blender.git] / source / blender / editors / space_time / time_ops.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <stdlib.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "DNA_scene_types.h"
34 #include "DNA_screen_types.h"
35 #include "DNA_space_types.h"
36 #include "DNA_windowmanager_types.h"
37
38 #include "BLI_blenlib.h"
39
40 #include "BKE_global.h"
41
42 #include "UI_interface.h"
43 #include "UI_view2d.h"
44
45 #include "RNA_access.h"
46 #include "RNA_define.h"
47
48 #include "WM_api.h"
49 #include "WM_types.h"
50
51 #include "ED_markers.h"
52
53 /* ********************** frame change operator ***************************/
54
55 static int change_frame_init(bContext *C, wmOperator *op)
56 {
57         SpaceTime *stime= C->area->spacedata.first;
58
59         stime->flag |= TIME_CFRA_NUM;
60         
61         return 1;
62 }
63
64 static void change_frame_apply(bContext *C, wmOperator *op)
65 {
66         int cfra;
67
68         cfra= RNA_int_get(op->ptr, "frame");
69
70         if(cfra < MINFRAME)
71                 cfra= MINFRAME;
72
73 #if 0
74         if( cfra!=CFRA || first )
75         {
76                 first= 0;
77                 CFRA= cfra;
78                 update_for_newframe_nodraw(0);  // 1= nosound
79                 timeline_force_draw(stime->redraws);
80         }
81         else PIL_sleep_ms(30);
82 #endif
83
84         if(cfra!=CFRA)
85                 CFRA= cfra;
86         
87         WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
88         /* XXX: add WM_NOTE_TIME_CHANGED? */
89 }
90
91 static void change_frame_exit(bContext *C, wmOperator *op)
92 {
93         SpaceTime *stime= C->area->spacedata.first;
94
95         stime->flag &= ~TIME_CFRA_NUM;
96 }
97
98 static int change_frame_exec(bContext *C, wmOperator *op)
99 {
100         if(!change_frame_init(C, op))
101                 return OPERATOR_CANCELLED;
102         
103         change_frame_apply(C, op);
104         change_frame_exit(C, op);
105         return OPERATOR_FINISHED;
106 }
107
108 static int frame_from_event(bContext *C, wmEvent *event)
109 {
110         SpaceTime *stime= C->area->spacedata.first;
111         ARegion *region= C->region;
112         int x, y;
113         float viewx;
114
115         x= event->x - region->winrct.xmin;
116         y= event->y - region->winrct.ymin;
117         UI_view2d_region_to_view(&stime->v2d, x, y, &viewx, NULL);
118
119         return (int)(viewx+0.5f);
120 }
121
122 static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
123 {
124         RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
125         change_frame_init(C, op);
126         change_frame_apply(C, op);
127
128         /* add temp handler */
129         WM_event_add_modal_handler(&C->region->handlers, op);
130
131         return OPERATOR_RUNNING_MODAL;
132 }
133
134 static int change_frame_cancel(bContext *C, wmOperator *op)
135 {
136         change_frame_exit(C, op);
137         return OPERATOR_CANCELLED;
138 }
139
140 static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
141 {
142         /* execute the events */
143         switch(event->type) {
144                 case MOUSEMOVE:
145                         RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
146                         change_frame_apply(C, op);
147                         break;
148                         
149                 case LEFTMOUSE:
150                         if(event->val==0) {
151                                 change_frame_exit(C, op);
152                                 WM_event_remove_modal_handler(&C->region->handlers, op);                                
153                                 return OPERATOR_FINISHED;
154                         }
155                         break;
156         }
157
158         return OPERATOR_RUNNING_MODAL;
159 }
160
161 void ED_TIME_OT_change_frame(wmOperatorType *ot)
162 {
163         PropertyRNA *prop;
164
165         /* identifiers */
166         ot->name= "Change frame";
167         ot->idname= "ED_TIME_OT_change_frame";
168         
169         /* api callbacks */
170         ot->exec= change_frame_exec;
171         ot->invoke= change_frame_invoke;
172         ot->cancel= change_frame_cancel;
173         ot->modal= change_frame_modal;
174
175         /* rna */
176         prop= RNA_def_property(ot->srna, "frame", PROP_INT, PROP_NONE);
177 }
178
179 /* ************************** registration **********************************/
180
181 void time_operatortypes(void)
182 {
183         WM_operatortype_append(ED_TIME_OT_change_frame);
184 }
185
186 void time_keymap(wmWindowManager *wm)
187 {
188         WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
189
190         /* markers (XXX move to function?) */
191         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
192         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_move", EVT_TWEAK_R, KM_ANY, 0, 0);
193         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
194         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect", RIGHTMOUSE, KM_PRESS, 0, 0);
195         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect_extend", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0);
196         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0);
197         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
198         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
199         
200         WM_keymap_add_item(&wm->timekeymap, "ED_MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
201                                                   
202         /* generates event, in end to make select work */
203         WM_keymap_verify_item(&wm->timekeymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0);
204         
205 }
206