Index: source/blender/src/drawipo.c =================================================================== --- source/blender/src/drawipo.c (revision 12935) +++ source/blender/src/drawipo.c (working copy) @@ -2319,6 +2319,8 @@ getmouseco_areawin(mvalo); mval[0]= mvalo[0]; mval[1]= mvalo[1]; + + printf("zoom event: %u (%i, %i)\n", event, mval[0], mval[1]); while( (get_mbut()&(L_MOUSE|M_MOUSE)) || is_wheel ) { @@ -2331,7 +2333,7 @@ wtemp = -0.0375; else wtemp = 0.03; - if(curarea->spacetype!=SPACE_BUTS) wtemp*= 3; + if(curarea->spacetype!=SPACE_BUTS && curarea->spacetype!=SPACE_OOPS) wtemp*= 3; dx= (float)(wtemp*(G.v2d->cur.xmax-G.v2d->cur.xmin)); dy= (float)(wtemp*(G.v2d->cur.ymax-G.v2d->cur.ymin)); @@ -2356,7 +2358,7 @@ wtemp = 0.03; else wtemp = -0.0375; - if(curarea->spacetype!=SPACE_BUTS) wtemp*= 3; + if(curarea->spacetype!=SPACE_BUTS && curarea->spacetype!=SPACE_OOPS) wtemp*= 3; dx= (float)(wtemp*(G.v2d->cur.xmax-G.v2d->cur.xmin)); dy= (float)(wtemp*(G.v2d->cur.ymax-G.v2d->cur.ymin)); @@ -2409,7 +2411,7 @@ mvalo[0]= mval[0]; mvalo[1]= mval[1]; } - + if( ELEM(curarea->spacetype, SPACE_NLA, SPACE_ACTION) ) { if(mvalo[0] < G.v2d->mask.xmin) { G.v2d->cur.ymin+= dy; @@ -2434,10 +2436,25 @@ } } else { - G.v2d->cur.xmin+= dx; - G.v2d->cur.xmax-= dx; - G.v2d->cur.ymin+= dy; - G.v2d->cur.ymax-= dy; + + printf(" (%f %f)\n", dx, dy); + if (1) { + float csz[2]; + + csz[0] = (G.v2d->mask.xmax-1) - G.v2d->mask.xmin; + csz[1] = (G.v2d->mask.ymax-1) - G.v2d->mask.ymin; + + G.v2d->cur.xmin+= (2.0 * dx * (mval[0]-G.v2d->mask.xmin) / csz[0]); + G.v2d->cur.xmax-= (2.0 * dx * (csz[0] - (mval[0]-G.v2d->mask.xmin)) / csz[0]); + G.v2d->cur.ymin+= (2.0 * dy * (mval[1]-G.v2d->mask.ymin) / csz[1]); + G.v2d->cur.ymax-= (2.0 * dy * (csz[1] - (mval[1]-G.v2d->mask.ymin)) / csz[1]); + } + else { + G.v2d->cur.xmin+= dx; + G.v2d->cur.xmax-= dx; + G.v2d->cur.ymin+= dy; + G.v2d->cur.ymax-= dy; + } } test_view2d(G.v2d, curarea->winx, curarea->winy); /* cur min max rects */ Index: source/blender/src/drawimage.c =================================================================== --- source/blender/src/drawimage.c (revision 12935) +++ source/blender/src/drawimage.c (working copy) @@ -2171,57 +2171,73 @@ G.sima->zoom = 1 / G.sima->zoom; } -static void image_zoom_set_factor(float zoomfac) +static void image_zoom_set_factor(float zoomfac, short *mouseloc) { SpaceImage *sima= curarea->spacedata.first; - int width, height; + float oldofs[2]; if (zoomfac <= 0.0f) return; + oldofs[0] = sima->xof; + oldofs[1] = sima->yof; + + if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS)) { + float mloca[2]; + mloca[0] = (mouseloc[0] - (curarea->winrct.xmax - curarea->winrct.xmin)*0.5f); + mloca[1] = (mouseloc[1] - (curarea->winrct.ymax - curarea->winrct.ymin)*0.5f); + sima->xof = ((mloca[0]+sima->xof*sima->zoom)*zoomfac - mloca[0])/(sima->zoom*zoomfac); + sima->yof = ((mloca[1]+sima->yof*sima->zoom)*zoomfac - mloca[1])/(sima->zoom*zoomfac); + } + sima->zoom *= zoomfac; - if (sima->zoom > 0.1f && sima->zoom < 4.0f) - return; - /* check zoom limits */ - calc_image_view(G.sima, 'f'); /* was 'p' are there any cases where this should be 'p'?*/ - width= 256; - height= 256; - if (sima->image) { - ImBuf *ibuf= imagewindow_get_ibuf(sima); + if (sima->zoom <= 0.1f || sima->zoom >= 4.0f) { + int width, height; - if (ibuf) { - float xim, yim; - /* I know a bit weak... but preview uses not actual image size */ - if(image_preview_active(curarea, &xim, &yim)) { - width= (int) xim; - height= (int) yim; + calc_image_view(G.sima, 'f'); /* was 'p' are there any cases where this should be 'p'?*/ + width= 256; + height= 256; + if (sima->image) { + ImBuf *ibuf= imagewindow_get_ibuf(sima); + + if (ibuf) { + float xim, yim; + /* I know a bit weak... but preview uses not actual image size */ + if(image_preview_active(curarea, &xim, &yim)) { + width= (int) xim; + height= (int) yim; + } + else { + width= ibuf->x; + height= ibuf->y; + } } - else { - width= ibuf->x; - height= ibuf->y; + } + width *= sima->zoom; + height *= sima->zoom; + + if (((width < 4) && (height < 4)) || + ((curarea->winrct.xmax - curarea->winrct.xmin) <= sima->zoom) || + ((curarea->winrct.ymax - curarea->winrct.ymin) <= sima->zoom)) { + sima->zoom /= zoomfac; + if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) != 0) { + sima->xof = oldofs[0]; + sima->yof = oldofs[1]; } } } - width *= sima->zoom; - height *= sima->zoom; - - if ((width < 4) && (height < 4)) - sima->zoom /= zoomfac; - else if((curarea->winrct.xmax - curarea->winrct.xmin) <= sima->zoom) - sima->zoom /= zoomfac; - else if((curarea->winrct.ymax - curarea->winrct.ymin) <= sima->zoom) - sima->zoom /= zoomfac; } void image_viewmove(int mode) { - short mval[2], mvalo[2], zoom0; + short mval[2], mvalo[2], zoom0, mval_area[2]; int oldcursor; Window *win; + getmouseco_areawin(mval_area); /* for zoom to mouse loc */ getmouseco_sc(mvalo); zoom0= G.sima->zoom; @@ -2244,7 +2260,7 @@ float factor; factor= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/300.0; - image_zoom_set_factor(factor); + image_zoom_set_factor(factor, mval_area); } mvalo[0]= mval[0]; @@ -2266,24 +2282,32 @@ void image_viewzoom(unsigned short event, int invert) { + short mval_area[2]; + float zoomfac = 1.0; SpaceImage *sima= curarea->spacedata.first; + getmouseco_areawin(mval_area); /* for zoom to mouse loc */ if(event==WHEELDOWNMOUSE || event==PADMINUS) - image_zoom_set_factor((U.uiflag & USER_WHEELZOOMDIR)? 1.25: 0.8); + zoomfac = (U.uiflag & USER_WHEELZOOMDIR)? 1.25: 0.8; else if(event==WHEELUPMOUSE || event==PADPLUSKEY) - image_zoom_set_factor((U.uiflag & USER_WHEELZOOMDIR)? 0.8: 1.25); + zoomfac = (U.uiflag & USER_WHEELZOOMDIR)? 0.8: 1.25; else if(event==PAD1) - sima->zoom= 1.0; + zoomfac = 1.0 / sima->zoom; else if(event==PAD2) - sima->zoom= (invert)? 2.0: 0.5; + zoomfac = ((invert)? 2.0: 0.5) / sima->zoom; else if(event==PAD4) - sima->zoom= (invert)? 4.0: 0.25; + zoomfac = ((invert)? 4.0: 0.25) / sima->zoom; else if(event==PAD8) - sima->zoom= (invert)? 8.0: 0.125; + zoomfac = ((invert)? 8.0: 0.125) / sima->zoom; + + if (zoomfac != 1.0) + image_zoom_set_factor(zoomfac, mval_area); /* ensure pixel exact locations for draw */ - sima->xof= (int)sima->xof; - sima->yof= (int)sima->yof; + if (sima->zoom == 1.0) { + sima->xof = (int)sima->xof; + sima->yof = (int)sima->yof; + } if(image_preview_active(curarea, NULL, NULL)) { /* recalculates new preview rect */