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