Orange: more work on float/exr buffers;
authorTon Roosendaal <ton@blender.org>
Tue, 10 Jan 2006 21:41:37 +0000 (21:41 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 10 Jan 2006 21:41:37 +0000 (21:41 +0000)
- EXR now saves and reads Zbuffers correctly
- EXR reading didn't set alpha to 1 yet when no alpha buffer was present

- ImageWindow: the "black point" only checked for the r value... now is OK
- ImageWindow: Curves panal has button "reset"
- ImageWindow: hold LMB drag shows rgba and z values. With SHIFT or CTRL it
  applies black/white point whilte dragging too
- ImageWindow: saving file copied the entire buffer... removed that. Also
  made the header print clear; this save only saves in own file type.

- Curves: zoom and drag now gets clamped by the Clipping value

- Imbuf: duplicate buffer only copied one quarter of to new buffer

source/blender/blenkernel/intern/colortools.c
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/makesdna/DNA_space_types.h
source/blender/src/butspace.c
source/blender/src/drawimage.c
source/blender/src/editsima.c
source/blender/src/header_image.c
source/blender/src/interface.c

index 85ef8f2b927a6256b35264f6acb597f13f1e1876..a7bad7d2f4b1351605321595c83ba24ae47023d4 100644 (file)
@@ -489,9 +489,9 @@ void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *ve
                
                fac= (vecin[0] - cumap->black[0])*cumap->bwmul[0];
                vecout[0]= curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, fac));
-               fac= (vecin[1] - cumap->black[0])*cumap->bwmul[1];
+               fac= (vecin[1] - cumap->black[1])*cumap->bwmul[1];
                vecout[1]= curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, fac));
-               fac= (vecin[2] - cumap->black[0])*cumap->bwmul[2];
+               fac= (vecin[2] - cumap->black[2])*cumap->bwmul[2];
                vecout[2]= curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, fac));
        }
        else {
@@ -507,7 +507,7 @@ void curvemapping_do_image(CurveMapping *cumap, Image *ima)
 {
        int pixel;
        
-       if(ima->ibuf==NULL)
+       if(ima==NULL || ima->ibuf==NULL)
                return;
        
        if(ima->ibuf->rect_float && ima->ibuf->rect) {
index 137795eec3f993b55e971392a0130d3dbac909d9..51d294d2d26134996a14e8f41688c1a84b6af888 100644 (file)
@@ -378,7 +378,7 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
                memcpy(ibuf2->rect, ibuf1->rect, x * y * sizeof(int));
        
        if (flags & IB_rectfloat)
-               memcpy(ibuf2->rect_float, ibuf1->rect_float, x * y * sizeof(float));
+               memcpy(ibuf2->rect_float, ibuf1->rect_float, 4 * x * y * sizeof(float));
 
        if (flags & IB_planes) 
                memcpy(*(ibuf2->planes),*(ibuf1->planes),ibuf1->depth * ibuf1->skipx * y * sizeof(int));
index 6e1c31901ce3a2907c2d47a6dabfd7f403361bbe..327c1ef02c58dd887c69317ad27cd3906cdb3295 100644 (file)
@@ -286,7 +286,6 @@ static short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags)
                if (write_zbuf)
                        frameBuffer.insert ("Z", Slice (UINT, (char *) ibuf->zbuf + 4*(height-1)*width,
                                                                                        sizeof(int), sizeof(int) * -width));
-               
                file->setFrameBuffer (frameBuffer);                               
                file->writePixels (height);                                       
                delete file;
@@ -344,8 +343,22 @@ static void exr_print_filecontents(InputFile *file)
                const Channel &channel = i.channel();
                printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
        }
+}
+
+static int exr_has_zbuffer(InputFile *file)
+{
+       const ChannelList &channels = file->header().channels();
        
+       for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+       {
+               const Channel &channel = i.channel();
+               if(strcmp("Z", i.name())==0)
+                       return 1;
+       }
+       return 0;
 }
+
+
 struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
 {
        struct ImBuf *ibuf = NULL;
@@ -386,9 +399,16 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
                                frameBuffer.insert ("R", Slice (FLOAT,  (char *) first, xstride, ystride));
                                frameBuffer.insert ("G", Slice (FLOAT,  (char *) (first+1), xstride, ystride));
                                frameBuffer.insert ("B", Slice (FLOAT,  (char *) (first+2), xstride, ystride));
-                               frameBuffer.insert ("A", Slice (FLOAT,  (char *) (first+3), xstride, ystride));
-                               
-                               // FIXME ? Would be able to read Z data or other channels here ! 
+                                                                                                                                               /* 1.0 is fill value */
+                               frameBuffer.insert ("A", Slice (FLOAT,  (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
+
+                               if(exr_has_zbuffer(file)) {
+                                       int *firstz;
+                                       
+                                       addzbufImBuf(ibuf);
+                                       firstz= ibuf->zbuf + (height-1)*width;
+                                       frameBuffer.insert ("Z", Slice (UINT,  (char *)firstz , sizeof(int), -width*sizeof(int)));
+                               }
                                
                                file->setFrameBuffer (frameBuffer);
                                file->readPixels (dw.min.y, dw.max.y);
index 50572f45d364a8523267dce9395e4a5a8419a2ee..bc5ef2042c29fe42bbe3a317ac72900e485b56e1 100644 (file)
@@ -466,6 +466,7 @@ typedef struct SpaceImaSel {
 #define SI_COORDFLOATS  512
 #define SI_PIXELSNAP   1024
 #define SI_LSCM_LIVE   2048
+#define SI_USE_ALPHA   4096
 
 /* SpaceText flags (moved from DNA_text_types.h) */
 
index 84d051c887a8117675949ec1863e228c9958ed0c..0041f49f018f33b5f17edc375766154c344b1f85 100644 (file)
@@ -262,16 +262,29 @@ static void curvemap_buttons_zoom_in(void *cumap_v, void *unused)
 static void curvemap_buttons_zoom_out(void *cumap_v, void *unused)
 {
        CurveMapping *cumap = cumap_v;
-       float d;
+       float d, d1;
        
-       /* we allow 20 times zoom */
+       /* we allow 20 times zoom, but dont view outside clip */
        if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
-               d= 0.15f*(cumap->curr.xmax - cumap->curr.xmin);
-               cumap->curr.xmin-= d;
-               cumap->curr.xmax+= d;
-               d= 0.15f*(cumap->curr.ymax - cumap->curr.ymin);
-               cumap->curr.ymin-= d;
-               cumap->curr.ymax+= d;
+               d= d1= 0.15f*(cumap->curr.xmax - cumap->curr.xmin);
+               
+               if(cumap->curr.xmin-d < cumap->clipr.xmin)
+                       d1= cumap->curr.xmin - cumap->clipr.xmin;
+               cumap->curr.xmin-= d1;
+               
+               if(cumap->curr.xmax+d > cumap->clipr.xmax)
+                       d1= -cumap->curr.xmax + cumap->clipr.xmax;
+               cumap->curr.xmax+= d1;
+               
+               d= d1= 0.15f*(cumap->curr.ymax - cumap->curr.ymin);
+               
+               if(cumap->curr.ymin-d < cumap->clipr.ymin)
+                       d1= cumap->curr.ymin - cumap->clipr.ymin;
+               cumap->curr.ymin-= d1;
+               
+               if(cumap->curr.ymax+d > cumap->clipr.ymax)
+                       d1= -cumap->curr.ymax + cumap->clipr.ymax;
+               cumap->curr.ymax+= d1;
        }
 }
 
index 9f1972ce04737f2ec8f82f5d576cdd6de0058f9d..17cb1d8d27b81a8041d7b2eb0d10b72dd2b0ba42 100644 (file)
@@ -920,9 +920,29 @@ static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES
        uiDefButBitS(block, TOG|BIT, IMAGEPAINT_TORUS, B_SIMABRUSHCHANGE, "Wrap", 890,1,50,19, &Gip.flag, 0, 0, 0, 0, "Enables torus wrapping");
 }
 
+static void image_panel_curves_reset(void *cumap_v, void *unused)
+{
+       CurveMapping *cumap = cumap_v;
+       int a;
+       
+       for(a=0; a<CM_TOT; a++)
+               curvemap_reset(cumap->cm+a, &cumap->clipr);
+       
+       cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f;
+       cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f;
+       curvemapping_set_black_white(cumap, NULL, NULL);
+       
+       curvemapping_changed(cumap, 0);
+       curvemapping_do_image(cumap, G.sima->image);
+       
+       allqueue(REDRAWIMAGE, 0);
+}
+
+
 static void image_panel_curves(short cntrl)    // IMAGE_HANDLER_PROPERTIES
 {
        uiBlock *block;
+       uiBut *bt;
        
        block= uiNewBlock(&curarea->uiblocks, "image_panel_curves", UI_EMBOSS, UI_HELV, curarea->win);
        uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
@@ -940,6 +960,9 @@ static void image_panel_curves(short cntrl) // IMAGE_HANDLER_PROPERTIES
                rect.ymin= 10; rect.ymax= 200;
                curvemap_buttons(block, G.sima->cumap, 'c', B_SIMACURVES, B_SIMAGEDRAW, &rect);
                
+               bt=uiDefBut(block, BUT, B_SIMARANGE, "Reset",   10, 160, 90, 19, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves");
+               uiButSetFunc(bt, image_panel_curves_reset, G.sima->cumap, NULL);
+               
                uiBlockBeginAlign(block);
                uiDefButF(block, NUM, B_SIMARANGE, "Min R:",    10, 120, 90, 19, G.sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level");
                uiDefButF(block, NUM, B_SIMARANGE, "Min G:",    10, 100, 90, 19, G.sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level");
@@ -949,6 +972,7 @@ static void image_panel_curves(short cntrl) // IMAGE_HANDLER_PROPERTIES
                uiDefButF(block, NUM, B_SIMARANGE, "Max R:",    10, 50, 90, 19, G.sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level");
                uiDefButF(block, NUM, B_SIMARANGE, "Max G:",    10, 30, 90, 19, G.sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level");
                uiDefButF(block, NUM, B_SIMARANGE, "Max B:",    10, 10, 90, 19, G.sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level");
+               
        }
 }
 
index 3b2a350e5900d31a1706e5d57a74ef83bb40705d..3075cb6b637c8a0ce65515eb788975ad38154516 100644 (file)
@@ -85,6 +85,8 @@
 #include "BDR_editobject.h"
 #include "BDR_unwrapper.h"
 
+#include "BMF_Api.h"
+
 #include "blendef.h"
 #include "mydevice.h"
 
@@ -1450,50 +1452,97 @@ int minmax_tface_uv(float *min, float *max)
        return sel;
 }
 
+static void sima_show_info(int x, int y, char *cp, float *fp, unsigned int *zp)
+{
+       short ofs;
+       char str[256];
+       
+       ofs= sprintf(str, "X: %d Y: %d ", x, y);
+       if(cp)
+               ofs+= sprintf(str+ofs, "| R: %d G: %d B: %d A: %d ", cp[0], cp[1], cp[2], cp[3]);
+       if(fp)
+               ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]);
+       if(zp)
+               ofs+= sprintf(str+ofs, "| Z: %x ", *zp);
+       
+       glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+       glEnable(GL_BLEND);
+       
+       glColor4f(.0,.0,.0,.25);
+       glRectf(0.0, 0.0, curarea->winx, 30.0);
+       glDisable(GL_BLEND);
+       
+       glColor3ub(255, 255, 255);
+       glRasterPos2i(10, 10);
+       
+       BMF_DrawString(G.fonts, str);
+
+}
+
 void sima_sample_color(void)
 {
        ImBuf *ibuf;
        float fx, fy;
-       short mval[2];
+       short mval[2], mvalo[2], firsttime=1;
        
        if(G.sima->image==NULL) return;
        if(G.sima->image->ibuf==NULL) return;
        ibuf= G.sima->image->ibuf;
        
        calc_image_view(G.sima, 'f');
+       getmouseco_areawin(mvalo);
        
-       getmouseco_areawin(mval);
-       areamouseco_to_ipoco(G.v2d, mval, &fx, &fy);
-       
-       if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
-               int x= (int) (fx*ibuf->x);
-               int y= (int) (fy*ibuf->y);
-               
-               if(x>=ibuf->x) x= ibuf->x-1;
-               if(y>=ibuf->y) y= ibuf->y-1;
+       while(get_mbut() & L_MOUSE) {
                
-               if(ibuf->rect) {
-                       char *cp= (char *)(ibuf->rect + y*ibuf->x + x);
-                       printf("rgba %d %d %d %d\n", cp[0], cp[1], cp[2], cp[3]);
-               }
-               if(ibuf->rect_float) {
-                       float *fp= (ibuf->rect_float + 4*(y*ibuf->x + x));
-                       printf("rgba %f %f %f %f\n", fp[0], fp[1], fp[2], fp[3]);
+               getmouseco_areawin(mval);
+               if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) {
+                       firsttime= 0;
+                       areamouseco_to_ipoco(G.v2d, mval, &fx, &fy);
                        
-                       if(G.sima->cumap) {
-                               if(G.qual & LR_CTRLKEY) {
-                                       curvemapping_set_black_white(G.sima->cumap, NULL, fp);
-                                       curvemapping_do_image(G.sima->cumap, G.sima->image);
-                                       allqueue(REDRAWIMAGE, 0);
+                       if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
+                               float *fp= NULL;
+                               unsigned int *zp= NULL;
+                               char *cp= NULL;
+                               
+                               int x= (int) (fx*ibuf->x);
+                               int y= (int) (fy*ibuf->y);
+                               
+                               if(x>=ibuf->x) x= ibuf->x-1;
+                               if(y>=ibuf->y) y= ibuf->y-1;
+                               
+                               if(ibuf->rect) {
+                                       cp= (char *)(ibuf->rect + y*ibuf->x + x);
                                }
-                               else if(G.qual & LR_SHIFTKEY) {
-                                       curvemapping_set_black_white(G.sima->cumap, fp, NULL);
-                                       curvemapping_do_image(G.sima->cumap, G.sima->image);
-                                       allqueue(REDRAWIMAGE, 0);
+                               if(ibuf->zbuf) {
+                                       zp= ibuf->zbuf + y*ibuf->x + x;
                                }
+                               if(ibuf->rect_float) {
+                                       fp= (ibuf->rect_float + 4*(y*ibuf->x + x));
+                                       
+                                       if(G.sima->cumap) {
+                                               if(G.qual & LR_CTRLKEY) {
+                                                       curvemapping_set_black_white(G.sima->cumap, NULL, fp);
+                                                       curvemapping_do_image(G.sima->cumap, G.sima->image);
+                                               }
+                                               else if(G.qual & LR_SHIFTKEY) {
+                                                       curvemapping_set_black_white(G.sima->cumap, fp, NULL);
+                                                       curvemapping_do_image(G.sima->cumap, G.sima->image);
+                                               }
+                                       }
+                               }
+                               
+                               scrarea_do_windraw(curarea);
+                               myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
+                               glLoadIdentity();
+                               sima_show_info(x, y, cp, fp, zp);
+                               screen_swapbuffers();
                        }
+                       
                }
-       }               
+               BIF_wait_for_statechange();
+       }
+       
+       scrarea_queue_winredraw(curarea);
 }
 
 
index 2e8608332a680bb9f4cfa186b1cc5bcbfd9c9118..38e8938b052f8e322d1a6aee4512beab73abe502 100644 (file)
@@ -185,19 +185,13 @@ static void save_paint(char *name)
                BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
 
                if (saveover(str)) {
-                       ibuf = IMB_dupImBuf(ima->ibuf);
-
-                       if (ibuf) {
-                               if (BIF_write_ibuf(ibuf, str)) {
-                                       BLI_strncpy(ima->name, name, sizeof(ima->name));
-                                       ima->ibuf->userflags &= ~IB_BITMAPDIRTY;
-                                       allqueue(REDRAWHEADERS, 0);
-                                       allqueue(REDRAWBUTSSHADING, 0);
-                               } else {
-                                       error("Couldn't write image: %s", str);
-                               }
-
-                               IMB_freeImBuf(ibuf);
+                       if (BIF_write_ibuf(ibuf, str)) {
+                               BLI_strncpy(ima->name, name, sizeof(ima->name));
+                               ima->ibuf->userflags &= ~IB_BITMAPDIRTY;
+                               allqueue(REDRAWHEADERS, 0);
+                               allqueue(REDRAWBUTSSHADING, 0);
+                       } else {
+                               error("Couldn't write image: %s", str);
                        }
                }
        }
@@ -335,9 +329,7 @@ void do_image_buttons(unsigned short event)
                if (ima) {
                        strcpy(name, ima->name);
                        if (ima->ibuf) {
-                               char str[32];   // sufficient for message
-                               save_image_filesel_str(str);
-                               activate_fileselect(FILE_SPECIAL, str, name, save_paint);
+                               activate_fileselect(FILE_SPECIAL, "Save in own image type", name, save_paint);
                        }
                }
                break;
@@ -706,9 +698,7 @@ static void do_image_imagemenu(void *arg, int event)
                if (ima) {
                        strcpy(name, ima->name);
                        if (ima->ibuf) {
-                               char str[32];   // sufficient for message
-                               save_image_filesel_str(str);
-                               activate_fileselect(FILE_SPECIAL, str, name, save_paint);
+                               activate_fileselect(FILE_SPECIAL, "Save in own image type", name, save_paint);
                        }
                }
                break;
index 05d7718da90163903e2f8ba43b37d78fb847c5e7..106286648b97531ae2d4687aac02624e53f8fdf5 100644 (file)
@@ -3335,6 +3335,8 @@ static int ui_do_but_CURVE(uiBut *but)
        CurveMap *cuma= cumap->cm+cumap->cur;
        CurveMapPoint *cmp= cuma->curve;
        float fx, fy, zoomx, zoomy, offsx, offsy;
+       float dist, mindist= 200.0f;    // 14 pixels radius
+       int a, sel= -1, retval= but->retval;
        short mval[2], mvalo[2];
        
        uiGetMouse(mywinget(), mval);
@@ -3356,113 +3358,123 @@ static int ui_do_but_CURVE(uiBut *but)
                ui_draw_but(but);
                ui_block_flush_back(but->block);
        }
-       else {
-               float dist, mindist= 200.0f;    // 14 pixels radius
-               int a, sel= -1;
-               
-               
-               /* check for selecting of a point */
-               for(a=0; a<cuma->totpoint; a++) {
-                       fx= but->x1 + zoomx*(cmp[a].x-offsx);
-                       fy= but->y1 + zoomy*(cmp[a].y-offsy);
-                       dist= (fx-mval[0])*(fx-mval[0]) + (fy-mval[1])*(fy-mval[1]);
-                       if(dist < mindist) {
-                               sel= a;
-                               mindist= dist;
-                       }
+       
+       
+       /* check for selecting of a point */
+       cmp= cuma->curve;       /* ctrl adds point, new malloc */
+       for(a=0; a<cuma->totpoint; a++) {
+               fx= but->x1 + zoomx*(cmp[a].x-offsx);
+               fy= but->y1 + zoomy*(cmp[a].y-offsy);
+               dist= (fx-mval[0])*(fx-mval[0]) + (fy-mval[1])*(fy-mval[1]);
+               if(dist < mindist) {
+                       sel= a;
+                       mindist= dist;
                }
-               /* ok, we move a point */
-               if(sel!= -1) {
-                       int moved_point;
-                       int moved_mouse= 0;
+       }
+       /* ok, we move a point */
+       if(sel!= -1) {
+               int moved_point;
+               int moved_mouse= 0;
 
-                       /* deselect all if this one is deselect. except if we hold shift */
-                       if((G.qual & LR_SHIFTKEY)==0 && (cmp[sel].flag & SELECT)==0)
-                               for(a=0; a<cuma->totpoint; a++)
-                                       cmp[a].flag &= ~SELECT;
-                       cmp[sel].flag |= SELECT;
+               /* deselect all if this one is deselect. except if we hold shift */
+               if((G.qual & LR_SHIFTKEY)==0 && (cmp[sel].flag & SELECT)==0)
+                       for(a=0; a<cuma->totpoint; a++)
+                               cmp[a].flag &= ~SELECT;
+               cmp[sel].flag |= SELECT;
+               
+               /* draw to show select updates */
+               ui_draw_but(but);
+               ui_block_flush_back(but->block);
+               
+               /* while move mouse, do move points around */
+               while(get_mbut() & L_MOUSE) {
                        
-                       /* draw to show select updates */
-                       ui_draw_but(but);
-                       ui_block_flush_back(but->block);
+                       uiGetMouse(mywinget(), mvalo);
                        
-                       /* while move mouse, do move points around */
-                       while(get_mbut() & L_MOUSE) {
+                       if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
+                               moved_mouse= 1;         /* for selection */
+                               moved_point= 0;         /* for ctrl grid, can't use orig coords because of sorting */
                                
-                               uiGetMouse(mywinget(), mvalo);
-                               
-                               if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
-                                       moved_mouse= 1;         /* for selection */
-                                       moved_point= 0;         /* for ctrl grid, can't use orig coords because of sorting */
-                                       
-                                       fx= (mvalo[0]-mval[0])/zoomx;
-                                       fy= (mvalo[1]-mval[1])/zoomy;
-                                       for(a=0; a<cuma->totpoint; a++) {
-                                               if(cmp[a].flag & SELECT) {
-                                                       float origx= cmp[a].x, origy= cmp[a].y;
-                                                       cmp[a].x+= fx;
-                                                       cmp[a].y+= fy;
-                                                       if( (get_qual() & LR_SHIFTKEY) ) {
-                                                               cmp[a].x= 0.125f*floor(0.5f + 8.0f*cmp[a].x);
-                                                               cmp[a].y= 0.125f*floor(0.5f + 8.0f*cmp[a].y);
-                                                       }
-                                                       if(cmp[a].x!=origx || cmp[a].y!=origy)
-                                                               moved_point= 1;
+                               fx= (mvalo[0]-mval[0])/zoomx;
+                               fy= (mvalo[1]-mval[1])/zoomy;
+                               for(a=0; a<cuma->totpoint; a++) {
+                                       if(cmp[a].flag & SELECT) {
+                                               float origx= cmp[a].x, origy= cmp[a].y;
+                                               cmp[a].x+= fx;
+                                               cmp[a].y+= fy;
+                                               if( (get_qual() & LR_SHIFTKEY) ) {
+                                                       cmp[a].x= 0.125f*floor(0.5f + 8.0f*cmp[a].x);
+                                                       cmp[a].y= 0.125f*floor(0.5f + 8.0f*cmp[a].y);
                                                }
-                                       }
-                                       curvemapping_changed(cumap, 0); /* no remove doubles */
-                                       
-                                       ui_draw_but(but);
-                                       ui_block_flush_back(but->block);
-                                       
-                                       if(moved_point) {
-                                               mval[0]= mvalo[0];
-                                               mval[1]= mvalo[1];
+                                               if(cmp[a].x!=origx || cmp[a].y!=origy)
+                                                       moved_point= 1;
                                        }
                                }
-                               BIF_wait_for_statechange();
-                       }
-                       
-                       if(moved_mouse==0) {
-                               /* deselect all, select one */
-                               if((G.qual & LR_SHIFTKEY)==0) {
-                                       for(a=0; a<cuma->totpoint; a++)
-                                               cmp[a].flag &= ~SELECT;
-                                       cmp[sel].flag |= SELECT;
-                               }
-                       }
-                       else 
-                               curvemapping_changed(cumap, 1); /* remove doubles */
-                       
-                       ui_draw_but(but);
-                       ui_block_flush_back(but->block);
-               }
-               else {
-                       /* we move the view */
-                       while(get_mbut() & L_MOUSE) {
+                               curvemapping_changed(cumap, 0); /* no remove doubles */
                                
-                               uiGetMouse(mywinget(), mvalo);
+                               ui_draw_but(but);
+                               ui_block_flush_back(but->block);
                                
-                               if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
-                                       fx= (mvalo[0]-mval[0])/zoomx;
-                                       fy= (mvalo[1]-mval[1])/zoomy;
-                                       cumap->curr.xmin-=fx;
-                                       cumap->curr.ymin-=fy;
-                                       cumap->curr.xmax-=fx;
-                                       cumap->curr.ymax-=fy;
-                                       
-                                       ui_draw_but(but);
-                                       ui_block_flush_back(but->block);
-                                       
+                               if(moved_point) {
                                        mval[0]= mvalo[0];
                                        mval[1]= mvalo[1];
                                }
                        }
                        BIF_wait_for_statechange();
                }
+               
+               if(moved_mouse==0) {
+                       /* deselect all, select one */
+                       if((G.qual & LR_SHIFTKEY)==0) {
+                               for(a=0; a<cuma->totpoint; a++)
+                                       cmp[a].flag &= ~SELECT;
+                               cmp[sel].flag |= SELECT;
+                       }
+               }
+               else 
+                       curvemapping_changed(cumap, 1); /* remove doubles */
+               
+               ui_draw_but(but);
+               ui_block_flush_back(but->block);
+       }
+       else {
+               /* we move the view */
+               retval= B_NOP;
+               
+               while(get_mbut() & L_MOUSE) {
+                       
+                       uiGetMouse(mywinget(), mvalo);
+                       
+                       if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
+                               fx= (mvalo[0]-mval[0])/zoomx;
+                               fy= (mvalo[1]-mval[1])/zoomy;
+                               
+                               /* clamp for clip */
+                               if(cumap->curr.xmin-fx < cumap->clipr.xmin)
+                                       fx= cumap->curr.xmin - cumap->clipr.xmin;
+                               else if(cumap->curr.xmax-fx > cumap->clipr.xmax)
+                                       fx= cumap->curr.xmax - cumap->clipr.xmax;
+                               if(cumap->curr.ymin-fy < cumap->clipr.ymin)
+                                       fy= cumap->curr.ymin - cumap->clipr.ymin;
+                               else if(cumap->curr.ymax-fy > cumap->clipr.ymax)
+                                       fy= cumap->curr.ymax - cumap->clipr.ymax;
+                               
+                               cumap->curr.xmin-=fx;
+                               cumap->curr.ymin-=fy;
+                               cumap->curr.xmax-=fx;
+                               cumap->curr.ymax-=fy;
+                               
+                               ui_draw_but(but);
+                               ui_block_flush_back(but->block);
+                               
+                               mval[0]= mvalo[0];
+                               mval[1]= mvalo[1];
+                       }
+               }
+               BIF_wait_for_statechange();
        }
        
-       return but->retval;
+       return retval;
 }
 
 /* ************************************************ */
@@ -4031,7 +4043,7 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                                                else sl->blockscale-= 0.1;
                                                CLAMP(sl->blockscale, 0.6, 1.0);
                                                addqueue(block->winq, REDRAW, 1);
-                                               retval= UI_CONT;
+                                               retval= UI_RETURN_OK;
                                        }
                                }
                        }