RNA
[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 /* ********************** frame change operator ***************************/
52
53 static int change_frame_init(bContext *C, wmOperator *op)
54 {
55         SpaceTime *stime= C->area->spacedata.first;
56
57         stime->flag |= TIME_CFRA_NUM;
58         
59         return 1;
60 }
61
62 static void change_frame_apply(bContext *C, wmOperator *op)
63 {
64         int cfra;
65
66         cfra= RNA_int_get(op->ptr, "frame");
67
68         if(cfra < MINFRAME)
69                 cfra= MINFRAME;
70
71 #if 0
72         if( cfra!=CFRA || first )
73         {
74                 first= 0;
75                 CFRA= cfra;
76                 update_for_newframe_nodraw(0);  // 1= nosound
77                 timeline_force_draw(stime->redraws);
78         }
79         else PIL_sleep_ms(30);
80 #endif
81
82         if(cfra!=CFRA)
83                 CFRA= cfra;
84         
85         WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
86         /* XXX: add WM_NOTE_TIME_CHANGED? */
87 }
88
89 static void change_frame_exit(bContext *C, wmOperator *op)
90 {
91         SpaceTime *stime= C->area->spacedata.first;
92
93         stime->flag &= ~TIME_CFRA_NUM;
94 }
95
96 static int change_frame_exec(bContext *C, wmOperator *op)
97 {
98         if(!change_frame_init(C, op))
99                 return OPERATOR_CANCELLED;
100         
101         change_frame_apply(C, op);
102         change_frame_exit(C, op);
103         return OPERATOR_FINISHED;
104 }
105
106 static int frame_from_event(bContext *C, wmEvent *event)
107 {
108         SpaceTime *stime= C->area->spacedata.first;
109         ARegion *region= C->region;
110         int x, y;
111         float viewx;
112
113         x= event->x - region->winrct.xmin;
114         y= event->y - region->winrct.ymin;
115         UI_view2d_region_to_view(&stime->v2d, x, y, &viewx, NULL);
116
117         return (int)(viewx+0.5f);
118 }
119
120 static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
121 {
122         RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
123         change_frame_init(C, op);
124         change_frame_apply(C, op);
125
126         /* add temp handler */
127         WM_event_add_modal_handler(&C->region->handlers, op);
128
129         return OPERATOR_RUNNING_MODAL;
130 }
131
132 static int change_frame_cancel(bContext *C, wmOperator *op)
133 {
134         change_frame_exit(C, op);
135         return OPERATOR_CANCELLED;
136 }
137
138 static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
139 {
140         /* execute the events */
141         switch(event->type) {
142                 case MOUSEMOVE:
143                         RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
144                         change_frame_apply(C, op);
145                         break;
146                         
147                 case LEFTMOUSE:
148                         if(event->val==0) {
149                                 change_frame_exit(C, op);
150                                 WM_event_remove_modal_handler(&C->region->handlers, op);                                
151                                 return OPERATOR_FINISHED;
152                         }
153                         break;
154         }
155
156         return OPERATOR_RUNNING_MODAL;
157 }
158
159 void ED_TIME_OT_change_frame(wmOperatorType *ot)
160 {
161         PropertyRNA *prop;
162
163         /* identifiers */
164         ot->name= "Change frame";
165         ot->idname= "ED_TIME_OT_change_frame";
166         
167         /* api callbacks */
168         ot->exec= change_frame_exec;
169         ot->invoke= change_frame_invoke;
170         ot->cancel= change_frame_cancel;
171         ot->modal= change_frame_modal;
172
173         /* rna */
174         prop= RNA_def_property(ot->srna, "frame", PROP_INT, PROP_NONE);
175 }
176
177 /* ************************** registration **********************************/
178
179 void time_operatortypes(void)
180 {
181         WM_operatortype_append(ED_TIME_OT_change_frame);
182 }
183
184 void time_keymap(wmWindowManager *wm)
185 {
186         WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
187 }
188