View2D: Scrollbars will now pan the view when MMB-dragged on
[blender-staging.git] / source / blender / editors / interface / view2d_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  * Contributor(s): Blender Foundation, Joshua Leung
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <math.h>
29
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_scene_types.h"
33 #include "DNA_screen_types.h"
34 #include "DNA_space_types.h"
35 #include "DNA_view2d_types.h"
36
37 #include "BLI_blenlib.h"
38
39 #include "BKE_global.h"
40 #include "BKE_utildefines.h"
41
42 #include "RNA_access.h"
43 #include "RNA_define.h"
44
45 #include "WM_api.h"
46 #include "WM_types.h"
47
48 #include "BIF_gl.h"
49
50 #include "UI_resources.h"
51 #include "UI_view2d.h"
52
53 /* ********************************************************* */
54 /* General Polling Funcs */
55
56 /* Check if mouse is within scrollbars 
57  *      - Returns appropriate code for match
58  *              'h' = in horizontal scrollbar
59  *              'v' = in vertical scrollbar
60  *              0 = not in scrollbar
61  *      
62  *      - x,y   = mouse coordinates in screen (not region) space
63  */
64 static short mouse_in_v2d_scrollers (const bContext *C, View2D *v2d, int x, int y)
65 {
66         ARegion *ar= C->region;
67         int co[2];
68         
69         /* clamp x,y to region-coordinates first */
70         co[0]= x - ar->winrct.xmin;
71         co[1]= y - ar->winrct.ymin;
72         
73         /* check if within scrollbars */
74         if (v2d->scroll & (HOR_SCROLL|HOR_SCROLLO)) {
75                 if (IN_2D_HORIZ_SCROLL(v2d, co)) return 'h';
76         }
77         if (v2d->scroll & VERT_SCROLL) {
78                 if (IN_2D_VERT_SCROLL(v2d, co)) return 'v';
79         }       
80         
81         /* not found */
82         return 0;
83
84
85
86 /* ********************************************************* */
87 /* VIEW PANNING OPERATOR                                                                 */
88
89 /*      This group of operators come in several forms:
90  *              1) Modal 'dragging' with MMB - where movement of mouse dictates amount to pan view by
91  *              2) Scrollwheel 'steps' - rolling mousewheel by one step moves view by predefined amount
92  *
93  *      In order to make sure this works, each operator must define the following RNA-Operator Props:
94  *              deltax, deltay  - define how much to move view by (relative to zoom-correction factor)
95  */
96
97 /* ------------------ Shared 'core' stuff ---------------------- */
98  
99 /* temp customdata for operator */
100 typedef struct v2dViewPanData {
101         ARegion *region;                /* region we're operating in */
102         View2D *v2d;                    /* view2d we're operating in */
103         
104         float facx, facy;               /* amount to move view relative to zoom */
105         
106                 /* options for version 1 */
107         int startx, starty;             /* mouse x/y values in window when operator was initiated */
108         int lastx, lasty;               /* previous x/y values of mouse in window */
109         
110         short in_scroller;              /* activated in scrollbar */
111 } v2dViewPanData;
112  
113 /* initialise panning customdata */
114 static int view_pan_init(bContext *C, wmOperator *op)
115 {
116         v2dViewPanData *vpd;
117         ARegion *ar;
118         View2D *v2d;
119         float winx, winy;
120         
121         /* regions now have v2d-data by default, so check for region */
122         if (C->region == NULL)
123                 return 0;
124         
125         /* set custom-data for operator */
126         vpd= MEM_callocN(sizeof(v2dViewPanData), "v2dViewPanData");
127         op->customdata= vpd;
128         
129         /* set pointers to owners */
130         vpd->region= ar= C->region;
131         vpd->v2d= v2d= &ar->v2d;
132         
133         /* calculate translation factor - based on size of view */
134         winx= (float)(ar->winrct.xmax - ar->winrct.xmin);
135         winy= (float)(ar->winrct.ymax - ar->winrct.ymin);
136         vpd->facx= (v2d->cur.xmax - v2d->cur.xmin) / winx;
137         vpd->facy= (v2d->cur.ymax - v2d->cur.ymin) / winy;
138         
139         return 1;
140 }
141
142 /* apply transform to view (i.e. adjust 'cur' rect) */
143 static void view_pan_apply(bContext *C, wmOperator *op)
144 {
145         v2dViewPanData *vpd= op->customdata;
146         View2D *v2d= vpd->v2d;
147         float dx, dy;
148         
149         /* calculate amount to move view by */
150         dx= vpd->facx * (float)RNA_int_get(op->ptr, "deltax");
151         dy= vpd->facy * (float)RNA_int_get(op->ptr, "deltay");
152         
153         /* only move view on an axis if change is allowed */
154         if ((v2d->keepofs & V2D_LOCKOFS_X)==0) {
155                 v2d->cur.xmin += dx;
156                 v2d->cur.xmax += dx;
157         }
158         if ((v2d->keepofs & V2D_LOCKOFS_Y)==0) {
159                 v2d->cur.ymin += dy;
160                 v2d->cur.ymax += dy;
161         }
162         
163         /* request updates to be done... */
164         WM_event_add_notifier(C, WM_NOTE_AREA_REDRAW, 0, NULL);
165         /* XXX: add WM_NOTE_TIME_CHANGED? */
166 }
167
168 /* cleanup temp customdata  */
169 static void view_pan_exit(bContext *C, wmOperator *op)
170 {
171         if (op->customdata) {
172                 MEM_freeN(op->customdata);
173                 op->customdata= NULL;                           
174         }
175
176  
177 /* ------------------ Modal Drag Version (1) ---------------------- */
178
179 /* for 'redo' only, with no user input */
180 static int view_pan_exec(bContext *C, wmOperator *op)
181 {
182         if (!view_pan_init(C, op))
183                 return OPERATOR_CANCELLED;
184         
185         view_pan_apply(C, op);
186         view_pan_exit(C, op);
187         return OPERATOR_FINISHED;
188 }
189
190 /* set up modal operator and relevant settings */
191 static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
192 {
193         v2dViewPanData *vpd;
194         View2D *v2d;
195         
196         /* set up customdata */
197         if (!view_pan_init(C, op))
198                 return OPERATOR_CANCELLED;
199         
200         vpd= op->customdata;
201         v2d= vpd->v2d;
202         
203         /* set initial settings */
204         vpd->startx= vpd->lastx= event->x;
205         vpd->starty= vpd->lasty= event->y;
206         RNA_int_set(op->ptr, "deltax", 0);
207         RNA_int_set(op->ptr, "deltay", 0);
208         
209         vpd->in_scroller= mouse_in_v2d_scrollers(C, v2d, event->x, event->y);
210         
211 #if 0 // XXX - enable this when cursors are working properly
212         if (v2d->keepofs & V2D_LOCKOFS_X)
213                 WM_set_cursor(C, BC_NS_SCROLLCURSOR);
214         else if (v2d->keepofs & V2D_LOCKOFS_Y)
215                 WM_set_cursor(C, BC_EW_SCROLLCURSOR);
216         else
217                 WM_set_cursor(C, BC_NSEW_SCROLLCURSOR);
218 #endif // XXX - enable this when cursors are working properly
219         
220         /* add temp handler */
221         WM_event_add_modal_handler(C, &C->window->handlers, op);
222
223         return OPERATOR_RUNNING_MODAL;
224 }
225
226 /* handle user input - calculations of mouse-movement need to be done here, not in the apply callback! */
227 static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
228 {
229         v2dViewPanData *vpd= op->customdata;
230         
231         /* execute the events */
232         switch (event->type) {
233                 case MOUSEMOVE:
234                 {
235                         /* calculate new delta transform, then store mouse-coordinates for next-time */
236                         switch (vpd->in_scroller) {
237                                 case 'h': /* horizontal scrollbar - so only horizontal scroll (inverse direction) */
238                                         RNA_int_set(op->ptr, "deltax", (event->x - vpd->lastx));
239                                         RNA_int_set(op->ptr, "deltay", 0);
240                                         break;
241                                 case 'v': /* vertical scrollbar - so only vertical scroll (inverse direction) */
242                                         RNA_int_set(op->ptr, "deltax", 0);
243                                         RNA_int_set(op->ptr, "deltay", (event->y - vpd->lasty));
244                                         break;
245                                 default:
246                                         RNA_int_set(op->ptr, "deltax", (vpd->lastx - event->x));
247                                         RNA_int_set(op->ptr, "deltay", (vpd->lasty - event->y));
248                                         break;
249                         }
250                         
251                         vpd->lastx= event->x;
252                         vpd->lasty= event->y;
253                         
254                         view_pan_apply(C, op);
255                 }
256                         break;
257                         
258                 case MIDDLEMOUSE:
259                         if (event->val==0) {
260                                 /* calculate overall delta mouse-movement for redo */
261                                 switch (vpd->in_scroller) {
262                                         case 'h': /* horizontal scrollbar - so only horizontal scroll (inverse direction) */
263                                                 RNA_int_set(op->ptr, "deltax", (vpd->lastx - vpd->startx));
264                                                 RNA_int_set(op->ptr, "deltay", 0);
265                                                 break;
266                                         case 'v': /* vertical scrollbar - so only vertical scroll (inverse direction) */
267                                                 RNA_int_set(op->ptr, "deltax", 0);
268                                                 RNA_int_set(op->ptr, "deltay", (vpd->lasty - vpd->starty));
269                                                 break;
270                                         default:
271                                                 RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
272                                                 RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
273                                                 break;
274                                 }
275                                 RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
276                                 RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
277                                 
278                                 view_pan_exit(C, op);
279                                 //WM_set_cursor(C, CURSOR_STD);         // XXX - enable this when cursors are working properly  
280                                 
281                                 return OPERATOR_FINISHED;
282                         }
283                         break;
284         }
285
286         return OPERATOR_RUNNING_MODAL;
287 }
288
289 void ED_View2D_OT_view_pan(wmOperatorType *ot)
290 {
291         PropertyRNA *prop;
292         
293         /* identifiers */
294         ot->name= "Pan View";
295         ot->idname= "ED_View2D_OT_view_pan";
296         
297         /* api callbacks */
298         ot->exec= view_pan_exec;
299         ot->invoke= view_pan_invoke;
300         ot->modal= view_pan_modal;
301         
302         /* rna - must keep these in sync with the other operators */
303         prop= RNA_def_property(ot->srna, "deltax", PROP_INT, PROP_NONE);
304         prop= RNA_def_property(ot->srna, "deltay", PROP_INT, PROP_NONE);
305 }
306
307 /* ------------------ Scrollwheel Versions (2) ---------------------- */
308
309 /* this operator only needs this single callback, where it callsthe view_pan_*() methods */
310 static int view_scrollright_exec(bContext *C, wmOperator *op)
311 {
312         /* initialise default settings (and validate if ok to run) */
313         if (!view_pan_init(C, op))
314                 return OPERATOR_CANCELLED;
315         
316         /* set RNA-Props - only movement in positive x-direction */
317         RNA_int_set(op->ptr, "deltax", 20);
318         RNA_int_set(op->ptr, "deltay", 0);
319         
320         /* apply movement, then we're done */
321         view_pan_apply(C, op);
322         view_pan_exit(C, op);
323         
324         return OPERATOR_FINISHED;
325 }
326
327 void ED_View2D_OT_view_scrollright(wmOperatorType *ot)
328 {
329         PropertyRNA *prop;
330         
331         /* identifiers */
332         ot->name= "Scroll Right";
333         ot->idname= "ED_View2D_OT_view_rightscroll";
334         
335         /* api callbacks */
336         ot->exec= view_scrollright_exec;
337         
338         /* rna - must keep these in sync with the other operators */
339         prop= RNA_def_property(ot->srna, "deltax", PROP_INT, PROP_NONE);
340         prop= RNA_def_property(ot->srna, "deltay", PROP_INT, PROP_NONE);
341 }
342
343
344
345 /* this operator only needs this single callback, where it callsthe view_pan_*() methods */
346 static int view_scrollleft_exec(bContext *C, wmOperator *op)
347 {
348         /* initialise default settings (and validate if ok to run) */
349         if (!view_pan_init(C, op))
350                 return OPERATOR_CANCELLED;
351         
352         /* set RNA-Props - only movement in negative x-direction */
353         RNA_int_set(op->ptr, "deltax", -20);
354         RNA_int_set(op->ptr, "deltay", 0);
355         
356         /* apply movement, then we're done */
357         view_pan_apply(C, op);
358         view_pan_exit(C, op);
359         
360         return OPERATOR_FINISHED;
361 }
362
363 void ED_View2D_OT_view_scrollleft(wmOperatorType *ot)
364 {
365         PropertyRNA *prop;
366         
367         /* identifiers */
368         ot->name= "Scroll Left";
369         ot->idname= "ED_View2D_OT_view_leftscroll";
370         
371         /* api callbacks */
372         ot->exec= view_scrollleft_exec;
373         
374         /* rna - must keep these in sync with the other operators */
375         prop= RNA_def_property(ot->srna, "deltax", PROP_INT, PROP_NONE);
376         prop= RNA_def_property(ot->srna, "deltay", PROP_INT, PROP_NONE);
377 }
378
379 /* this operator only needs this single callback, where it callsthe view_pan_*() methods */
380 static int view_scrolldown_exec(bContext *C, wmOperator *op)
381 {
382         /* initialise default settings (and validate if ok to run) */
383         if (!view_pan_init(C, op))
384                 return OPERATOR_CANCELLED;
385         
386         /* set RNA-Props - only movement in positive x-direction */
387         RNA_int_set(op->ptr, "deltax", 0);
388         RNA_int_set(op->ptr, "deltay", -20);
389         
390         /* apply movement, then we're done */
391         view_pan_apply(C, op);
392         view_pan_exit(C, op);
393         
394         return OPERATOR_FINISHED;
395 }
396
397 void ED_View2D_OT_view_scrolldown(wmOperatorType *ot)
398 {
399         PropertyRNA *prop;
400         
401         /* identifiers */
402         ot->name= "Scroll Down";
403         ot->idname= "ED_View2D_OT_view_downscroll";
404         
405         /* api callbacks */
406         ot->exec= view_scrolldown_exec;
407         
408         /* rna - must keep these in sync with the other operators */
409         prop= RNA_def_property(ot->srna, "deltax", PROP_INT, PROP_NONE);
410         prop= RNA_def_property(ot->srna, "deltay", PROP_INT, PROP_NONE);
411 }
412
413
414
415 /* this operator only needs this single callback, where it callsthe view_pan_*() methods */
416 static int view_scrollup_exec(bContext *C, wmOperator *op)
417 {
418         /* initialise default settings (and validate if ok to run) */
419         if (!view_pan_init(C, op))
420                 return OPERATOR_CANCELLED;
421         
422         /* set RNA-Props - only movement in negative x-direction */
423         RNA_int_set(op->ptr, "deltax", 0);
424         RNA_int_set(op->ptr, "deltay", 20);
425         
426         /* apply movement, then we're done */
427         view_pan_apply(C, op);
428         view_pan_exit(C, op);
429         
430         return OPERATOR_FINISHED;
431 }
432
433 void ED_View2D_OT_view_scrollup(wmOperatorType *ot)
434 {
435         PropertyRNA *prop;
436         
437         /* identifiers */
438         ot->name= "Scroll Up";
439         ot->idname= "ED_View2D_OT_view_upscroll";
440         
441         /* api callbacks */
442         ot->exec= view_scrollup_exec;
443         
444         /* rna - must keep these in sync with the other operators */
445         prop= RNA_def_property(ot->srna, "deltax", PROP_INT, PROP_NONE);
446         prop= RNA_def_property(ot->srna, "deltay", PROP_INT, PROP_NONE);
447 }
448
449 /* ********************************************************* */
450 /* VIEW ZOOMING OPERATOR                                                                 */
451
452 /*      This group of operators come in several forms:
453  *              1) Modal 'dragging' with MMB - where movement of mouse dictates amount to zoom view by
454  *              2) Scrollwheel 'steps' - rolling mousewheel by one step moves view by predefined amount
455  *              3) Pad +/- Keys - pressing each key moves the zooms the view by a predefined amount
456  *
457  *      In order to make sure this works, each operator must define the following RNA-Operator Props:
458  *              zoomfacx, zoomfacy      - sometimes it's still useful to have non-uniform scaling  
459  */
460
461 /* ------------------ Shared 'core' stuff ---------------------- */
462
463 /* temp customdata for operator */
464 typedef struct v2dViewZoomData {
465         ARegion *region;                /* region we're operating in */
466         View2D *v2d;                    /* view2d we're operating in */
467         
468         int startx, starty;             /* mouse x/y values in window when operator was initiated */
469         int lastx, lasty;               /* previous x/y values of mouse in window */
470 } v2dViewZoomData;
471  
472 /* initialise zooming customdata */
473 static int view_zoom_init(bContext *C, wmOperator *op)
474 {
475         v2dViewZoomData *vzd;
476         ARegion *ar;
477         
478         /* regions now have v2d-data by default, so check for region */
479         if (C->region == NULL)
480                 return 0;
481         
482         /* set custom-data for operator */
483         vzd= MEM_callocN(sizeof(v2dViewZoomData), "v2dViewZoomData");
484         op->customdata= vzd;
485         
486         /* set pointers to owners */
487         vzd->region= ar= C->region;
488         vzd->v2d= &ar->v2d;
489         
490         return 1;
491 }
492
493 /* apply transform to view (i.e. adjust 'cur' rect) */
494 static void view_zoom_apply(bContext *C, wmOperator *op)
495 {
496         v2dViewZoomData *vzd= op->customdata;
497         View2D *v2d= vzd->v2d;
498         float dx, dy;
499         
500         /* calculate amount to move view by */
501         dx= (v2d->cur.xmax - v2d->cur.xmin) * (float)RNA_float_get(op->ptr, "zoomfacx");
502         dy= (v2d->cur.ymax - v2d->cur.ymin) * (float)RNA_float_get(op->ptr, "zoomfacy");
503         
504         /* only move view on an axis if change is allowed */
505         // FIXME: this still only allows for zooming around 'center' of view... userdefined center is more useful!
506         if ((v2d->keepofs & V2D_LOCKOFS_X)==0) {
507                 v2d->cur.xmin += dx;
508                 v2d->cur.xmax -= dx;
509         }
510         if ((v2d->keepofs & V2D_LOCKOFS_Y)==0) {
511                 v2d->cur.ymin += dy;
512                 v2d->cur.ymax -= dy;
513         }
514         
515         /* request updates to be done... */
516         WM_event_add_notifier(C, WM_NOTE_AREA_REDRAW, 0, NULL);
517         /* XXX: add WM_NOTE_TIME_CHANGED? */
518 }
519
520 /* cleanup temp customdata  */
521 static void view_zoom_exit(bContext *C, wmOperator *op)
522 {
523         if (op->customdata) {
524                 MEM_freeN(op->customdata);
525                 op->customdata= NULL;                           
526         }
527 }
528
529 /* ------------------ Single-step non-modal zoom (2 and 3) ---------------------- */
530
531 /* this operator only needs this single callback, where it callsthe view_zoom_*() methods */
532 // FIXME: this should be invoke (with event pointer), so that we can do non-modal but require pointer for centerpoint
533 static int view_zoomin_exec(bContext *C, wmOperator *op)
534 {
535         /* initialise default settings (and validate if ok to run) */
536         if (!view_zoom_init(C, op))
537                 return OPERATOR_CANCELLED;
538         
539         /* set RNA-Props - zooming in by uniform factor */
540         RNA_float_set(op->ptr, "zoomfacx", 0.0375);
541         RNA_float_set(op->ptr, "zoomfacy", 0.0375);
542         
543         /* apply movement, then we're done */
544         view_zoom_apply(C, op);
545         view_zoom_exit(C, op);
546         
547         return OPERATOR_FINISHED;
548 }
549
550 void ED_View2D_OT_view_zoomin(wmOperatorType *ot)
551 {
552         PropertyRNA *prop;
553         
554         /* identifiers */
555         ot->name= "Zoom In";
556         ot->idname= "ED_View2D_OT_view_zoomin";
557         
558         /* api callbacks */
559         ot->exec= view_zoomin_exec;
560         
561         /* rna - must keep these in sync with the other operators */
562         prop= RNA_def_property(ot->srna, "zoomfacx", PROP_FLOAT, PROP_NONE);
563         prop= RNA_def_property(ot->srna, "zoomfacy", PROP_FLOAT, PROP_NONE);
564 }
565
566
567
568 /* this operator only needs this single callback, where it callsthe view_zoom_*() methods */
569 // FIXME: this should be invoke (with event pointer), so that we can do non-modal but require pointer for centerpoint
570 static int view_zoomout_exec(bContext *C, wmOperator *op)
571 {
572         /* initialise default settings (and validate if ok to run) */
573         if (!view_zoom_init(C, op))
574                 return OPERATOR_CANCELLED;
575         
576         /* set RNA-Props - zooming in by uniform factor */
577         RNA_float_set(op->ptr, "zoomfacx", -0.0375);
578         RNA_float_set(op->ptr, "zoomfacy", -0.0375);
579         
580         /* apply movement, then we're done */
581         view_zoom_apply(C, op);
582         view_zoom_exit(C, op);
583         
584         return OPERATOR_FINISHED;
585 }
586
587 void ED_View2D_OT_view_zoomout(wmOperatorType *ot)
588 {
589         PropertyRNA *prop;
590         
591         /* identifiers */
592         ot->name= "Zoom Out";
593         ot->idname= "ED_View2D_OT_view_zoomout";
594         
595         /* api callbacks */
596         ot->exec= view_zoomout_exec;
597         
598         /* rna - must keep these in sync with the other operators */
599         prop= RNA_def_property(ot->srna, "zoomfacx", PROP_FLOAT, PROP_NONE);
600         prop= RNA_def_property(ot->srna, "zoomfacy", PROP_FLOAT, PROP_NONE);
601 }
602
603 /* ********************************************************* */
604 /* Scrollers */
605
606  
607 /* ********************************************************* */
608 /* Registration */
609
610 void ui_view2d_operatortypes(void)
611 {
612         WM_operatortype_append(ED_View2D_OT_view_pan);
613         
614         WM_operatortype_append(ED_View2D_OT_view_scrollleft);
615         WM_operatortype_append(ED_View2D_OT_view_scrollright);
616         WM_operatortype_append(ED_View2D_OT_view_scrollup);
617         WM_operatortype_append(ED_View2D_OT_view_scrolldown);
618         
619         WM_operatortype_append(ED_View2D_OT_view_zoomin);
620         WM_operatortype_append(ED_View2D_OT_view_zoomout);
621 }
622
623 void UI_view2d_keymap(wmWindowManager *wm)
624 {
625         ui_view2d_operatortypes();
626         
627         /* pan/scroll operators */
628         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
629         
630         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_rightscroll", WHEELDOWNMOUSE, KM_ANY, KM_CTRL, 0);
631         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_leftscroll", WHEELUPMOUSE, KM_ANY, KM_CTRL, 0);
632         
633         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_downscroll", WHEELDOWNMOUSE, KM_ANY, KM_SHIFT, 0);
634         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_upscroll", WHEELUPMOUSE, KM_ANY, KM_SHIFT, 0);
635         
636         /* zoom */
637         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomout", WHEELUPMOUSE, KM_ANY, 0, 0);
638         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomin", WHEELDOWNMOUSE, KM_ANY, 0, 0);
639         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomout", PADMINUS, KM_PRESS, 0, 0);
640         WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_zoomin", PADPLUSKEY, KM_PRESS, 0, 0);
641         
642         
643         /* scrollbars */
644         //WM_keymap_add_item(&wm->view2dkeymap, "ED_V2D_OT_scrollbar_activate", MOUSEMOVE, 0, 0, 0);
645 }
646