2.5
[blender-staging.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 #include <math.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_scene_types.h"
35 #include "DNA_screen_types.h"
36 #include "DNA_space_types.h"
37 #include "DNA_windowmanager_types.h"
38
39 #include "BLI_blenlib.h"
40
41 #include "BKE_global.h"
42
43 #include "UI_interface.h"
44 #include "UI_view2d.h"
45
46 #include "RNA_access.h"
47 #include "RNA_define.h"
48
49 #include "WM_api.h"
50 #include "WM_types.h"
51
52 #include "ED_markers.h"
53
54 /* ********************** frame change operator ***************************/
55
56 static int change_frame_init(bContext *C, wmOperator *op)
57 {
58         SpaceTime *stime= C->area->spacedata.first;
59
60         stime->flag |= TIME_CFRA_NUM;
61         
62         return 1;
63 }
64
65 static void change_frame_apply(bContext *C, wmOperator *op)
66 {
67         int cfra;
68
69         cfra= RNA_int_get(op->ptr, "frame");
70
71         if(cfra < MINFRAME)
72                 cfra= MINFRAME;
73
74 #if 0
75         if( cfra!=CFRA || first )
76         {
77                 first= 0;
78                 CFRA= cfra;
79                 update_for_newframe_nodraw(0);  // 1= nosound
80                 timeline_force_draw(stime->redraws);
81         }
82         else PIL_sleep_ms(30);
83 #endif
84
85         if(cfra!=CFRA)
86                 CFRA= cfra;
87         
88         WM_event_add_notifier(C, WM_NOTE_SCREEN_CHANGED, 0, NULL);
89         /* XXX: add WM_NOTE_TIME_CHANGED? */
90 }
91
92 static void change_frame_exit(bContext *C, wmOperator *op)
93 {
94         SpaceTime *stime= C->area->spacedata.first;
95
96         stime->flag &= ~TIME_CFRA_NUM;
97 }
98
99 static int change_frame_exec(bContext *C, wmOperator *op)
100 {
101         if(!change_frame_init(C, op))
102                 return OPERATOR_CANCELLED;
103         
104         change_frame_apply(C, op);
105         change_frame_exit(C, op);
106         return OPERATOR_FINISHED;
107 }
108
109 static int frame_from_event(bContext *C, wmEvent *event)
110 {
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(&region->v2d, x, y, &viewx, NULL);
118
119         return (int)floor(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, &C->window->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                                 return OPERATOR_FINISHED;
153                         }
154                         break;
155         }
156
157         return OPERATOR_RUNNING_MODAL;
158 }
159
160 void ED_TIME_OT_change_frame(wmOperatorType *ot)
161 {
162         PropertyRNA *prop;
163
164         /* identifiers */
165         ot->name= "Change frame";
166         ot->idname= "ED_TIME_OT_change_frame";
167         
168         /* api callbacks */
169         ot->exec= change_frame_exec;
170         ot->invoke= change_frame_invoke;
171         ot->cancel= change_frame_cancel;
172         ot->modal= change_frame_modal;
173
174         /* rna */
175         prop= RNA_def_property(ot->srna, "frame", PROP_INT, PROP_NONE);
176 }
177
178 /* ************************** registration **********************************/
179
180 void time_operatortypes(void)
181 {
182         WM_operatortype_append(ED_TIME_OT_change_frame);
183 }
184
185 void time_keymap(wmWindowManager *wm)
186 {
187         WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
188
189         /* markers (XXX move to function?) */
190         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
191         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_move", EVT_TWEAK_R, KM_ANY, 0, 0);
192         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
193         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect", RIGHTMOUSE, KM_PRESS, 0, 0);
194         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect_extend", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0);
195         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0);
196         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
197         WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
198         
199         WM_keymap_add_item(&wm->timekeymap, "ED_MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
200                                                   
201         /* generates event, in end to make select work */
202         WM_keymap_verify_item(&wm->timekeymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0);
203         
204 }
205