Index: intern/ghost/GHOST_Types.h =================================================================== --- intern/ghost/GHOST_Types.h (revision 25746) +++ intern/ghost/GHOST_Types.h (working copy) @@ -151,6 +151,7 @@ GHOST_kEventButtonDown, /// Mouse button event GHOST_kEventButtonUp, /// Mouse button event GHOST_kEventWheel, /// Mouse wheel event + GHOST_kEventTrackpad, /// Trackpad event GHOST_kEventNDOFMotion, /// N degree of freedom device motion event GHOST_kEventNDOFButton, /// N degree of freedom device button event @@ -373,7 +374,29 @@ GHOST_TInt32 z; } GHOST_TEventWheelData; +typedef enum { + GHOST_kTrackpadEventUnknown =0, + GHOST_kTrackpadEventScroll, + GHOST_kTrackpadEventRotate, + GHOST_kTrackpadEventSwipe, + GHOST_kTrackpadEventMagnify +} GHOST_TTrackpadEventSubTypes; + +typedef struct { + /** The event subtype */ + GHOST_TTrackpadEventSubTypes subtype; + /** The x-location of the trackpad event */ + GHOST_TInt32 x; + /** The y-location of the trackpad event */ + GHOST_TInt32 y; + /** The x-delta or value of the trackpad event */ + GHOST_TInt32 deltaX; + /** The y-delta (currently only for scroll subtype) of the trackpad event */ + GHOST_TInt32 deltaY; +} GHOST_TEventTrackpadData; + + typedef enum { GHOST_kDragnDropTypeUnknown =0, GHOST_kDragnDropTypeFilenames, /*Array of strings representing file names (full path) */ Index: intern/ghost/intern/GHOST_EventTrackpad.h =================================================================== --- intern/ghost/intern/GHOST_EventTrackpad.h (revision 0) +++ intern/ghost/intern/GHOST_EventTrackpad.h (revision 0) @@ -0,0 +1,71 @@ +/** + * $Id$ + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): James Deery 11/2009 + * Damien Plisson 12/2009 + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** + * @file GHOST_EventTrackpad.h + * Declaration of GHOST_EventTrackpad class. + */ + +#ifndef _GHOST_EVENT_TRACKPAD_H_ +#define _GHOST_EVENT_TRACKPAD_H_ + +#include "GHOST_Event.h" + +/** + * Trackpad (scroll, magnify, rotate, ...) event. + */ +class GHOST_EventTrackpad : public GHOST_Event +{ +public: + /** + * Constructor. + * @param msec The time this event was generated. + * @param type The type of this event. + * @param subtype The subtype of the event. + * @param x The x-delta of the pan event. + * @param y The y-delta of the pan event. + */ + GHOST_EventTrackpad(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TTrackpadEventSubTypes subtype, GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY) + : GHOST_Event(msec, GHOST_kEventTrackpad, window) + { + m_trackpadEventData.subtype = subtype; + m_trackpadEventData.x = x; + m_trackpadEventData.y = y; + m_trackpadEventData.deltaX = deltaX; + m_trackpadEventData.deltaY = deltaY; + m_data = &m_trackpadEventData; + } + +protected: + /** The mouse pan data */ + GHOST_TEventTrackpadData m_trackpadEventData; +}; + + +#endif // _GHOST_EVENT_PAN_H_ + Index: intern/ghost/intern/GHOST_SystemCocoa.mm =================================================================== --- intern/ghost/intern/GHOST_SystemCocoa.mm (revision 25746) +++ intern/ghost/intern/GHOST_SystemCocoa.mm (working copy) @@ -41,6 +41,7 @@ #include "GHOST_EventCursor.h" #include "GHOST_EventWheel.h" #include "GHOST_EventNDOF.h" +#include "GHOST_EventTrackpad.h" #include "GHOST_EventDragnDrop.h" #include "GHOST_TimerManager.h" @@ -376,7 +377,25 @@ #pragma mark defines for 10.6 api not documented in 10.5 #ifndef MAC_OS_X_VERSION_10_6 +enum { + /* The following event types are available on some hardware on 10.5.2 and later */ + NSEventTypeGesture = 29, + NSEventTypeMagnify = 30, + NSEventTypeSwipe = 31, + NSEventTypeRotate = 18, + NSEventTypeBeginGesture = 19, + NSEventTypeEndGesture = 20 +}; +@interface NSEvent(GestureEvents) +/* This message is valid for events of type NSEventTypeMagnify, on 10.5.2 or later */ +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +- (float)magnification; // change in magnification. +#else +- (CGFloat)magnification; // change in magnification. +#endif +@end + @interface NSEvent(SnowLeopardEvents) /* modifier keys currently down. This returns the state of devices combined with synthesized events at the moment, independent of which events @@ -596,7 +615,7 @@ } [NSApp finishLaunching]; - + [pool drain]; } return success; @@ -845,7 +864,9 @@ case NSScrollWheel: case NSOtherMouseDown: case NSOtherMouseUp: - case NSOtherMouseDragged: + case NSOtherMouseDragged: + case NSEventTypeMagnify: + case NSEventTypeRotate: handleMouseEvent(event); break; @@ -854,11 +875,9 @@ handleTabletEvent(event,[event type]); break; - /* Trackpad features, will need OS X 10.6 for implementation + /* Trackpad features, fired only from OS X 10.5.2 case NSEventTypeGesture: - case NSEventTypeMagnify: case NSEventTypeSwipe: - case NSEventTypeRotate: case NSEventTypeBeginGesture: case NSEventTypeEndGesture: break; */ @@ -1315,16 +1334,48 @@ case NSScrollWheel: { - GHOST_TInt32 delta; - - double deltaF = [event deltaY]; - if (deltaF == 0.0) break; //discard trackpad delta=0 events - - delta = deltaF > 0.0 ? 1 : -1; - pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta)); + /* Send Wheel event if sent from the mouse, trackpad event otherwise */ + if ([event subtype] == NSMouseEventSubtype) { + GHOST_TInt32 delta; + + double deltaF = [event deltaY]; + if (deltaF == 0.0) break; //discard trackpad delta=0 events + + delta = deltaF > 0.0 ? 1 : -1; + pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta)); + } + else { + NSPoint mousePos = [event locationInWindow]; + double dx = [event deltaX]; + double dy = -[event deltaY]; + + if ((dx == 0) && (dy == 0)) break; + + /* Quadratic acceleration */ + dx = dx*(fabs(dx)+0.5); + if (dx<0.0) dx-=0.5; else dx+=0.5; + dy = dy*(fabs(dy)+0.5); + if (dy<0.0) dy-=0.5; else dy+=0.5; + + pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, mousePos.x, mousePos.y, dx, dy)); + } } break; + case NSEventTypeMagnify: + { + NSPoint mousePos = [event locationInWindow]; + pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, mousePos.x, mousePos.y, + [event magnification]*250.0 + 0.1, 0)); + } + break; + + case NSEventTypeRotate: + { + NSPoint mousePos = [event locationInWindow]; + pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, mousePos.x, mousePos.y, + [event rotation] * 5.0, 0)); + } default: return GHOST_kFailure; break; Index: source/blender/makesrna/intern/rna_wm.c =================================================================== --- source/blender/makesrna/intern/rna_wm.c (revision 25746) +++ source/blender/makesrna/intern/rna_wm.c (working copy) @@ -84,6 +84,9 @@ {SELECTMOUSE, "SELECTMOUSE", 0, "Select", ""}, {0, "", 0, NULL, NULL}, {MOUSEMOVE, "MOUSEMOVE", 0, "Move", ""}, + {MOUSEPAN, "TRACKPADPAN", 0, "Mouse/Trackpad Pan", ""}, + {MOUSEZOOM, "TRACKPADZOOM", 0, "Mouse/Trackpad Zoom", ""}, + {MOUSEROTATE, "MOUSEROTATE", 0, "Mouse/Trackpad Rotate", ""}, {0, "", 0, NULL, NULL}, {WHEELUPMOUSE, "WHEELUPMOUSE", 0, "Wheel Up", ""}, {WHEELDOWNMOUSE, "WHEELDOWNMOUSE", 0, "Wheel Down", ""}, @@ -111,6 +114,9 @@ {SELECTMOUSE, "SELECTMOUSE", 0, "Select Mouse", ""}, {0, "", 0, NULL, NULL}, {MOUSEMOVE, "MOUSEMOVE", 0, "Mouse Move", ""}, + {MOUSEPAN, "TRACKPADPAN", 0, "Mouse/Trackpad Pan", ""}, + {MOUSEZOOM, "TRACKPADZOOM", 0, "Mouse/Trackpad Zoom", ""}, + {MOUSEROTATE, "MOUSEROTATE", 0, "Mouse/Trackpad Rotate", ""}, {0, "", 0, NULL, NULL}, {WHEELUPMOUSE, "WHEELUPMOUSE", 0, "Wheel Up", ""}, {WHEELDOWNMOUSE, "WHEELDOWNMOUSE", 0, "Wheel Down", ""}, Index: source/blender/windowmanager/intern/wm_event_system.c =================================================================== --- source/blender/windowmanager/intern/wm_event_system.c (revision 25746) +++ source/blender/windowmanager/intern/wm_event_system.c (working copy) @@ -1760,6 +1760,40 @@ } break; } + case GHOST_kEventTrackpad: { + if (win->active) { + GHOST_TEventTrackpadData * pd = customdata; + switch (pd->subtype) { + case GHOST_kTrackpadEventMagnify: + event.type = MOUSEZOOM; + break; + case GHOST_kTrackpadEventRotate: + event.type = MOUSEROTATE; + break; + case GHOST_kTrackpadEventScroll: + default: + event.type= MOUSEPAN; + break; + } +#if defined(__APPLE__) && defined(GHOST_COCOA) + //Cocoa already uses coordinates with y=0 at bottom, and returns inwindow coordinates on mouse moved event + event.x= evt->x = pd->x; + event.y = evt->y = pd->y; +#else + int cx, cy; + GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy); + event.x= evt->x= cx; + event.y= evt->y= (win->sizey-1) - cy; +#endif + // Use prevx/prevy so we can calculate the delta later + event.prevx= event.x - pd->deltaX; + event.prevy= event.y - pd->deltaY; + + update_tablet_data(win, &event); + wm_event_add(win, &event); + } + break; + } /* mouse button */ case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { Index: source/blender/windowmanager/wm_event_types.h =================================================================== --- source/blender/windowmanager/wm_event_types.h (revision 25746) +++ source/blender/windowmanager/wm_event_types.h (working copy) @@ -56,9 +56,13 @@ /* only use if you want user option switch possible */ #define ACTIONMOUSE 0x005 #define SELECTMOUSE 0x006 -/* Extra mouse buttons */ + /* Extra mouse buttons */ #define BUTTON4MOUSE 0x007 #define BUTTON5MOUSE 0x008 + /* Extra trackpad gestures */ +#define MOUSEPAN 0x00e +#define MOUSEZOOM 0x00f +#define MOUSEROTATE 0x010 /* defaults from ghost */ #define WHEELUPMOUSE 0x00a #define WHEELDOWNMOUSE 0x00b @@ -67,7 +71,7 @@ #define WHEELOUTMOUSE 0x00d -/* SYSTEM : 0x01x */ +/* SYSTEM : 0x01xx */ #define INPUTCHANGE 0x0103 /* input connected or disconnected */ #define WINDEACTIVATE 0x0104 /* window is deactivated, focus lost */ @@ -202,7 +206,7 @@ #define ISKEYBOARD(event) (event >=' ' && event <=320) /* test whether the event is a mouse button */ -#define ISMOUSE(event) (event >= LEFTMOUSE && event <= WHEELOUTMOUSE) +#define ISMOUSE(event) (event >= LEFTMOUSE && event <= MOUSEROTATE) /* test whether the event is timer event */ #define ISTIMER(event) (event >= TIMER && event <= TIMERAUTOSAVE) Index: source/blender/editors/space_text/space_text.c =================================================================== --- source/blender/editors/space_text/space_text.c (revision 25746) +++ source/blender/editors/space_text/space_text.c (working copy) @@ -313,6 +313,7 @@ WM_keymap_add_item(keymap, "TEXT_OT_overwrite_toggle", INSERTKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_scroll", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "TEXT_OT_scroll", MOUSEPAN, 0, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, 0, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select", 1); Index: source/blender/editors/space_outliner/outliner.c =================================================================== --- source/blender/editors/space_outliner/outliner.c (revision 25746) +++ source/blender/editors/space_outliner/outliner.c (working copy) @@ -5104,6 +5104,9 @@ str += sprintf(str, formatstr, "Wheel Down", WHEELDOWNMOUSE); str += sprintf(str, formatstr, "Wheel In", WHEELINMOUSE); str += sprintf(str, formatstr, "Wheel Out", WHEELOUTMOUSE); + str += sprintf(str, formatstr, "Mouse/Trackpad Pan", MOUSEPAN); + str += sprintf(str, formatstr, "Mouse/Trackpad Zoom", MOUSEZOOM); + str += sprintf(str, formatstr, "Mouse/Trackpad Rotate", MOUSEROTATE); return string; } Index: source/blender/editors/space_view3d/view3d_edit.c =================================================================== --- source/blender/editors/space_view3d/view3d_edit.c (revision 25746) +++ source/blender/editors/space_view3d/view3d_edit.c (working copy) @@ -248,7 +248,7 @@ float ofs[3], dyn_ofs[3]; short use_dyn_ofs; - int origx, origy, oldx, oldy; + int origx, origy, origz, oldx, oldy, oldz; int origkey; /* the key that triggered the operator */ } ViewOpsData; @@ -298,6 +298,7 @@ QUATCOPY(vod->oldquat, rv3d->viewquat); vod->origx= vod->oldx= event->x; vod->origy= vod->oldy= event->y; + vod->origz= vod->oldz= 0; /* 3-axis mouse unhandled for now, but needed for trackpad 3rd axis */ vod->origkey= event->type; /* the key that triggered the operator. */ vod->use_dyn_ofs= (U.uiflag & USER_ORBIT_SELECTION) ? 1:0; @@ -477,13 +478,15 @@ } -static void viewrotate_apply(ViewOpsData *vod, int x, int y) +static void viewrotate_apply(ViewOpsData *vod, int x, int y, int z) { RegionView3D *rv3d= vod->rv3d; rv3d->view= 0; /* need to reset everytime because of view snapping */ - if (U.flag & USER_TRACKBALL) { + /* Hack to force turntable mode for MOUSEROTATE events + Change to use better computation for this 3rd axis rotation ? */ + if ((U.flag & USER_TRACKBALL) && (z==0)) { float phi, si, q1[4], dvec[3], newvec[3]; calctrackballvec(&vod->ar->winrct, x, y, newvec); @@ -534,6 +537,7 @@ float m[3][3]; float m_inv[3][3]; float xvec[3] = {1,0,0}; + float zvec[3] = {0,0,1}; /* Sensitivity will control how fast the viewport rotates. 0.0035 was obtained experimentally by looking at viewport rotation sensitivities on other modeling programs. */ @@ -545,7 +549,7 @@ invert_m3_m3(m_inv,m); /* Determine the direction of the x vector (for rotating up and down) */ - /* This can likely be compuated directly from the quaternion. */ + /* This can likely be computed directly from the quaternion. */ mul_m3_v3(m_inv,xvec); /* Perform the up/down rotation */ @@ -563,7 +567,7 @@ mul_qt_v3(q1, rv3d->ofs); add_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs); } - + /* Perform the orbital rotation */ phi = sensitivity * vod->reverse * (x - vod->oldx); q1[0] = cos(phi); @@ -577,6 +581,26 @@ mul_qt_v3(q1, rv3d->ofs); add_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs); } + + /* Perform the left/right rotation */ + /* Determine the direction of the z vector (for rotating left and right) */ + mul_m3_v3(m_inv,zvec); + + /* Perform the left/right rotation */ + phi = sensitivity * -(z - vod->oldz); + si = sin(phi); + q1[0] = cos(phi); + q1[1] = si * zvec[0]; + q1[2] = si * zvec[1]; + q1[3] = si * zvec[2]; + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1); + + if (vod->use_dyn_ofs) { + conjugate_qt(q1); /* conj == inv for unit quat */ + sub_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs); + mul_qt_v3(q1, rv3d->ofs); + add_v3_v3v3(rv3d->ofs, rv3d->ofs, vod->dyn_ofs); + } } /* check for view snap */ @@ -640,7 +664,7 @@ } if(event_code==VIEW_APPLY) { - viewrotate_apply(vod, event->x, event->y); + viewrotate_apply(vod, event->x, event->y, 0); } else if (event_code==VIEW_CONFIRM) { request_depth_update(CTX_wm_region_view3d(C)); @@ -673,11 +697,31 @@ vod->rv3d->persp= RV3D_PERSP; ED_region_tag_redraw(vod->ar); } + + if (event->type == MOUSEPAN) { + viewrotate_apply(vod, event->prevx, event->prevy, 0); + request_depth_update(CTX_wm_region_view3d(C)); + + viewops_data_free(C, op); + + return OPERATOR_FINISHED; + } + else if (event->type == MOUSEROTATE) { + /* hack to manage lack of 3rd axis in event struct */ + vod->origz = vod->oldz = event->x; + viewrotate_apply(vod, event->x, event->y, event->prevx); + request_depth_update(CTX_wm_region_view3d(C)); + + viewops_data_free(C, op); + + return OPERATOR_FINISHED; + } + else { + /* add temp handler */ + WM_event_add_modal_handler(C, op); - /* add temp handler */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; + return OPERATOR_RUNNING_MODAL; + } } static int ED_operator_view3d_rotate(bContext *C) @@ -809,13 +853,23 @@ /* makes op->customdata */ viewops_data_create(C, op, event); - /* add temp handler */ - WM_event_add_modal_handler(C, op); + if (event->type == MOUSEPAN) { + ViewOpsData *vod= op->customdata; + viewmove_apply(vod, event->prevx, event->prevy); + request_depth_update(CTX_wm_region_view3d(C)); + + viewops_data_free(C, op); + + return OPERATOR_FINISHED; + } + else { + /* add temp handler */ + WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; + return OPERATOR_RUNNING_MODAL; + } } - void VIEW3D_OT_move(wmOperatorType *ot) { @@ -907,11 +961,11 @@ } -static void viewzoom_apply(ViewOpsData *vod, int x, int y) +static void viewzoom_apply(ViewOpsData *vod, int x, int y, short viewzoom) { float zfac=1.0; - if(U.viewzoom==USER_ZOOM_CONT) { + if(viewzoom==USER_ZOOM_CONT) { double time= PIL_check_seconds_timer(); float time_step= (float)(time - vod->timer_lastdraw); @@ -919,7 +973,7 @@ zfac = 1.0f + (((float)(vod->origx - x + vod->origy - y)/20.0) * time_step); vod->timer_lastdraw= time; } - else if(U.viewzoom==USER_ZOOM_SCALE) { + else if(viewzoom==USER_ZOOM_SCALE) { int ctr[2], len1, len2; // method which zooms based on how far you move the mouse @@ -953,7 +1007,7 @@ view_zoom_mouseloc(vod->ar, zfac, vod->oldx, vod->oldy); - if ((U.uiflag & USER_ORBIT_ZBUF) && (U.viewzoom==USER_ZOOM_CONT) && (vod->rv3d->persp==RV3D_PERSP)) { + if ((U.uiflag & USER_ORBIT_ZBUF) && (viewzoom==USER_ZOOM_CONT) && (vod->rv3d->persp==RV3D_PERSP)) { float upvec[3], mat[3][3]; /* Secret apricot feature, translate the view when in continues mode */ @@ -1002,7 +1056,7 @@ } if(event_code==VIEW_APPLY) { - viewzoom_apply(vod, event->x, event->y); + viewzoom_apply(vod, event->x, event->y, U.viewzoom); } else if (event_code==VIEW_CONFIRM) { request_depth_update(CTX_wm_region_view3d(C)); @@ -1073,13 +1127,34 @@ vod= op->customdata; - vod->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); - vod->timer_lastdraw= PIL_check_seconds_timer(); + if (event->type == MOUSEZOOM) { + if (U.uiflag & USER_ZOOM_INVERT) /* Bypass Zoom invert flag */ + SWAP(int, event->x, event->prevx); - /* add temp handler */ - WM_event_add_modal_handler(C, op); + if (U.uiflag & USER_ZOOM_DOLLY_HORIZ) { + vod->origx = vod->oldx = event->x; + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY); + } + else { + + /* Set y move = x move as MOUSEZOOM uses only x axis */ + vod->origy = vod->oldy = event->x; + viewzoom_apply(vod, event->x, event->prevx, USER_ZOOM_DOLLY); + } + request_depth_update(CTX_wm_region_view3d(C)); + + viewops_data_free(C, op); + return OPERATOR_FINISHED; + } + else { + vod->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); + vod->timer_lastdraw= PIL_check_seconds_timer(); - return OPERATOR_RUNNING_MODAL; + /* add temp handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; + } } return OPERATOR_FINISHED; } Index: source/blender/editors/space_view3d/view3d_ops.c =================================================================== --- source/blender/editors/space_view3d/view3d_ops.c (revision 25746) +++ source/blender/editors/space_view3d/view3d_ops.c (working copy) @@ -133,6 +133,11 @@ WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, KM_ALT, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEROTATE, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEZOOM, 0, 0, 0); + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELINMOUSE, KM_PRESS, 0, 0)->ptr, "delta", 1); Index: source/blender/editors/space_image/image_ops.c =================================================================== --- source/blender/editors/space_image/image_ops.c (revision 25746) +++ source/blender/editors/space_image/image_ops.c (working copy) @@ -214,8 +214,21 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) { - view_pan_init(C, op, event); - return OPERATOR_RUNNING_MODAL; + if (event->type == MOUSEPAN) { + SpaceImage *sima= CTX_wm_space_image(C); + float offset[2]; + + offset[0]= (event->x - event->prevx)/sima->zoom; + offset[1]= (event->y - event->prevy)/sima->zoom; + RNA_float_set_array(op->ptr, "offset", offset); + + view_pan_exec(C, op); + return OPERATOR_FINISHED; + } + else { + view_pan_init(C, op, event); + return OPERATOR_RUNNING_MODAL; + } } static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) @@ -331,8 +344,22 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) { - view_zoom_init(C, op, event); - return OPERATOR_RUNNING_MODAL; + if (event->type == MOUSEZOOM) { + SpaceImage *sima= CTX_wm_space_image(C); + ARegion *ar= CTX_wm_region(C); + float factor; + + factor= 1.0 + (event->x-event->prevx+event->y-event->prevy)/300.0f; + RNA_float_set(op->ptr, "factor", factor); + sima_zoom_set(sima, ar, sima->zoom*factor); + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; + } + else { + view_zoom_init(C, op, event); + return OPERATOR_RUNNING_MODAL; + } } static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) Index: source/blender/editors/space_image/space_image.c =================================================================== --- source/blender/editors/space_image/space_image.c (revision 25746) +++ source/blender/editors/space_image/space_image.c (working copy) @@ -219,12 +219,14 @@ WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MOUSEPAN, 0, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f); Index: source/blender/editors/interface/view2d_ops.c =================================================================== --- source/blender/editors/interface/view2d_ops.c (revision 25746) +++ source/blender/editors/interface/view2d_ops.c (working copy) @@ -199,6 +199,16 @@ /* set initial settings */ vpd->startx= vpd->lastx= event->x; vpd->starty= vpd->lasty= event->y; + + if (event->type == MOUSEPAN) { + RNA_int_set(op->ptr, "deltax", event->prevx - event->x); + RNA_int_set(op->ptr, "deltay", event->prevy - event->y); + + view_pan_apply(C, op); + view_pan_exit(C, op); + return OPERATOR_FINISHED; + } + RNA_int_set(op->ptr, "deltax", 0); RNA_int_set(op->ptr, "deltay", 0); @@ -777,6 +787,15 @@ vzd= op->customdata; v2d= vzd->v2d; + if (event->type == MOUSEZOOM) { + RNA_float_set(op->ptr, "deltax", event->prevx - event->x); + RNA_float_set(op->ptr, "deltay", event->prevy - event->y); + + view_zoomdrag_apply(C, op); + view_zoomdrag_exec(C, op); + return OPERATOR_FINISHED; + } + /* set initial settings */ vzd->lastx= event->x; vzd->lasty= event->y; @@ -1455,6 +1474,8 @@ WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MOUSEPAN, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_right", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_left", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0); @@ -1477,6 +1498,7 @@ /* zoom - drag */ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEZOOM, 0, 0, 0); /* borderzoom - drag */ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0); @@ -1487,9 +1509,11 @@ /* Alternative keymap for buttons listview */ keymap= WM_keymap_find(keyconf, "View2D Buttons List", 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MOUSEPAN, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEZOOM, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_reset", HOMEKEY, KM_PRESS, 0, 0);