34380fe4fd6dfe648afe0cabe3bd1d591a50860f
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 /** \file blender/editors/space_time/time_ops.c
30  *  \ingroup sptime
31  */
32
33
34 #include <stdlib.h>
35 #include <math.h>
36
37 #include "DNA_scene_types.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_utildefines.h"
41
42 #include "BKE_context.h"
43
44 #include "ED_screen.h"
45
46 #include "WM_api.h"
47 #include "WM_types.h"
48
49 #include "time_intern.h"
50
51 /* ****************** Start/End Frame Operators *******************************/
52
53 static int time_set_sfra_exec (bContext *C, wmOperator *UNUSED(op))
54 {
55         Scene *scene= CTX_data_scene(C);
56         int frame= CFRA;
57         
58         if (scene == NULL)
59                 return OPERATOR_CANCELLED;
60                 
61         /* if 'end frame' (Preview Range or Actual) is less than 'frame', 
62          * clamp 'frame' to 'end frame'
63          */
64         if (PEFRA < frame) frame= PEFRA;
65                 
66         /* if Preview Range is defined, set the 'start' frame for that */
67         if (PRVRANGEON)
68                 scene->r.psfra= frame;
69         else
70                 scene->r.sfra= frame;
71         
72         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
73         
74         return OPERATOR_FINISHED;
75 }
76
77 static void TIME_OT_start_frame_set (wmOperatorType *ot)
78 {
79         /* identifiers */
80         ot->name= "Set Start Frame";
81         ot->idname= "TIME_OT_start_frame_set";
82         ot->description="Set the start frame";
83         
84         /* api callbacks */
85         ot->exec= time_set_sfra_exec;
86         ot->poll= ED_operator_timeline_active;
87         
88         /* flags */
89         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
90 }       
91
92
93 static int time_set_efra_exec (bContext *C, wmOperator *UNUSED(op))
94 {
95         Scene *scene= CTX_data_scene(C);
96         int frame= CFRA;
97         
98         if (scene == NULL)
99                 return OPERATOR_CANCELLED;
100                 
101         /* if 'start frame' (Preview Range or Actual) is greater than 'frame', 
102          * clamp 'frame' to 'end frame'
103          */
104         if (PSFRA > frame) frame= PSFRA;
105                 
106         /* if Preview Range is defined, set the 'end' frame for that */
107         if (PRVRANGEON)
108                 scene->r.pefra= frame;
109         else
110                 scene->r.efra= frame;
111         
112         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
113         
114         return OPERATOR_FINISHED;
115 }
116
117 static void TIME_OT_end_frame_set (wmOperatorType *ot)
118 {
119         /* identifiers */
120         ot->name= "Set End Frame";
121         ot->idname= "TIME_OT_end_frame_set";
122         ot->description="Set the end frame";
123         
124         /* api callbacks */
125         ot->exec= time_set_efra_exec;
126         ot->poll= ED_operator_timeline_active;
127         
128         /* flags */
129         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
130 }
131
132 /* ************************ View All Operator *******************************/
133
134 static int time_view_all_exec (bContext *C, wmOperator *UNUSED(op))
135 {
136         Scene *scene= CTX_data_scene(C);
137         ARegion *ar= CTX_wm_region(C);
138         View2D *v2d= (ar) ? &ar->v2d : NULL;
139         float extra;
140         
141         if ELEM(NULL, scene, ar)
142                 return OPERATOR_CANCELLED;
143                 
144         /* set extents of view to start/end frames (Preview Range too) */
145         v2d->cur.xmin= (float)PSFRA;
146         v2d->cur.xmax= (float)PEFRA;
147         
148         /* we need an extra "buffer" factor on either side so that the endpoints are visible */
149         extra= 0.01f * (v2d->cur.xmax - v2d->cur.xmin);
150         v2d->cur.xmin -= extra;
151         v2d->cur.xmax += extra;
152         
153         /* this only affects this TimeLine instance, so just force redraw of this region */
154         ED_region_tag_redraw(ar);
155         
156         return OPERATOR_FINISHED;
157 }
158
159 static void TIME_OT_view_all (wmOperatorType *ot)
160 {
161         /* identifiers */
162         ot->name= "View All";
163         ot->idname= "TIME_OT_view_all";
164         ot->description= "Show the entire playable frame range";
165         
166         /* api callbacks */
167         ot->exec= time_view_all_exec;
168         ot->poll= ED_operator_timeline_active;
169         
170         /* flags */
171         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
172 }
173
174 /* ************************** registration **********************************/
175
176 void time_operatortypes(void)
177 {
178         WM_operatortype_append(TIME_OT_start_frame_set);
179         WM_operatortype_append(TIME_OT_end_frame_set);
180         WM_operatortype_append(TIME_OT_view_all);
181 }
182
183 void time_keymap(wmKeyConfig *keyconf)
184 {
185         wmKeyMap *keymap= WM_keymap_find(keyconf, "Timeline", SPACE_TIME, 0);
186         
187         WM_keymap_add_item(keymap, "TIME_OT_start_frame_set", SKEY, KM_PRESS, 0, 0);
188         WM_keymap_add_item(keymap, "TIME_OT_end_frame_set", EKEY, KM_PRESS, 0, 0);
189         WM_keymap_add_item(keymap, "TIME_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
190 }
191