Merging trunk up to rev 40959
[blender.git] / source / blender / editors / interface / interface_handlers.c
index a3d072c32201b7eddc6df31b8eaed742d5c3c994..29b270df5dbd0c823bc9dd59f3fea90ead9b5cfe 100644 (file)
@@ -56,6 +56,7 @@
 #include "BKE_idprop.h"
 #include "BKE_report.h"
 #include "BKE_texture.h"
+#include "BKE_tracking.h"
 #include "BKE_unit.h"
 
 #include "ED_screen.h"
@@ -253,7 +254,7 @@ static uiBut *ui_but_last(uiBlock *block)
 static int ui_is_a_warp_but(uiBut *but)
 {
        if(U.uiflag & USER_CONTINUOUS_MOUSE)
-               if(ELEM3(but->type, NUM, NUMABS, HSVCIRCLE))
+               if(ELEM4(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW))
                        return TRUE;
 
        return FALSE;
@@ -916,6 +917,13 @@ static void ui_apply_but_WAVEFORM(bContext *C, uiBut *but, uiHandleButtonData *d
        data->applied= 1;
 }
 
+static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data)
+{
+       ui_apply_but_func(C, but);
+       data->retval= but->retval;
+       data->applied= 1;
+}
+
 
 static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, int interactive)
 {
@@ -1045,6 +1053,9 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
                case WAVEFORM:
                        ui_apply_but_WAVEFORM(C, but, data);
                        break;
+               case TRACKPREVIEW:
+                       ui_apply_but_TRACKPREVIEW(C, but, data);
+                       break;
                default:
                        break;
        }
@@ -1307,12 +1318,12 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
        }
        /* mouse inside the widget */
        else if (x >= startx) {
-               float aspect= (but->block->aspect);
+               const float aspect_sqrt= sqrtf(but->block->aspect);
                
                but->pos= strlen(origstr)-but->ofs;
                
                /* XXX does not take zoom level into account */
-               while (startx + aspect*BLF_width(fstyle->uifont_id, origstr+but->ofs) > x) {
+               while (startx + aspect_sqrt * BLF_width(fstyle->uifont_id, origstr+but->ofs) > x) {
                        if (but->pos <= 0) break;
                        but->pos--;
                        origstr[but->pos+but->ofs] = 0;
@@ -1368,7 +1379,7 @@ static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char asc
        return changed;
 }
 
-static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, int jump)
+static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, int jump, int jump_all)
 {
        const char *str= data->str;
        const int len= strlen(str);
@@ -1377,23 +1388,28 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction
 
        /* special case, quit selection and set cursor */
        if (has_sel && !select) {
-               if (direction) {
-                       but->selsta = but->pos = but->selend;
+               if (jump_all) {
+                       but->selsta = but->selend= but->pos = direction ? len : 0;
                }
                else {
-                       but->pos = but->selend = but->selsta;
+                       if (direction) {
+                               but->selsta = but->pos = but->selend;
+                       }
+                       else {
+                               but->pos = but->selend = but->selsta;
+                       }
                }
                data->selextend = 0;
        }
        else {
                if(direction) { /* right*/
                        if(jump) {
-                               /* jump betweenn special characters (/,\,_,-, etc.),
+                               /* jump between special characters (/,\,_,-, etc.),
                                 * look at function test_special_char() for complete
                                 * list of special character, ctr -> */
                                while(but->pos < len) {
                                        but->pos++;
-                                       if(test_special_char(str[but->pos])) break;
+                                       if(!jump_all && test_special_char(str[but->pos])) break;
                                }
                        }
                        else {
@@ -1403,13 +1419,25 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction
                }
                else { /* left */
                        if(jump) {
-                               /* jump betweenn special characters (/,\,_,-, etc.),
+
+                               /* left only: compensate for index/change in direction */
+                               if(but->pos > 0) {
+                                       but->pos--;
+                               }
+
+                               /* jump between special characters (/,\,_,-, etc.),
                                 * look at function test_special_char() for complete
                                 * list of special character, ctr -> */
                                while(but->pos > 0){
                                        but->pos--;
-                                       if(test_special_char(str[but->pos])) break;
+                                       if(!jump_all && test_special_char(str[but->pos])) break;
                                }
+
+                               /* left only: compensate for index/change in direction */
+                               if((but->pos != 0) && ABS(pos_prev - but->pos) > 1) {
+                                       but->pos++;
+                               }
+
                        }
                        else {
                                if(but->pos>0) but->pos--;
@@ -1464,37 +1492,12 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction
        }
 }
 
-static void ui_textedit_move_end(uiBut *but, uiHandleButtonData *data, int direction, int select)
+static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, const int all, const int jump)
 {
-       const char *str= data->str;
-
-       if(direction) { /* right */
-               if(select) {
-                       but->selsta = but->pos;
-                       but->selend = strlen(str);
-                       data->selextend = EXTEND_RIGHT;
-               } else {
-                       but->selsta = but->selend = but->pos= strlen(str);
-               }
-       }
-       else { /* left */
-               if(select) {
-                       but->selend = but->pos;
-                       but->selsta = 0;
-                       data->selextend = EXTEND_LEFT;
-               } else {
-                       but->selsta = but->selend = but->pos= 0;
-               }
-       }
-}
-
-static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, int all)
-{
-       char *str;
-       int len, x, changed= 0;
+       char *str= data->str;
+       const int len= strlen(str);
 
-       str= data->str;
-       len= strlen(str);
+       int x, changed= 0;
 
        if(all) {
                if(len) changed=1;
@@ -1506,9 +1509,24 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
                        changed= ui_textedit_delete_selection(but, data);
                }
                else if(but->pos>=0 && but->pos<len) {
+                       int step;
+
+                       if (jump) {
+                               x = but->pos;
+                               step= 0;
+                               while(x < len) {
+                                       x++;
+                                       step++;
+                                       if(test_special_char(str[x])) break;
+                               }
+                       }
+                       else {
+                               step= 1;
+                       }
+
                        for(x=but->pos; x<len; x++)
-                               str[x]= str[x+1];
-                       str[len-1]='\0';
+                               str[x]= str[x+step];
+                       str[len-step]='\0';
                        changed= 1;
                }
        }
@@ -1518,11 +1536,26 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
                                changed= ui_textedit_delete_selection(but, data);
                        }
                        else if(but->pos>0) {
+                               int step;
+
+                               if (jump) {
+                                       x = but->pos;
+                                       step= 0;
+                                       while(x > 0) {
+                                               x--;
+                                               step++;
+                                               if((step > 1) && test_special_char(str[x])) break;
+                                       }
+                               }
+                               else {
+                                       step= 1;
+                               }
+
                                for(x=but->pos; x<len; x++)
-                                       str[x-1]= str[x];
-                               str[len-1]='\0';
+                                       str[x-step]= str[x];
+                               str[len-step]='\0';
 
-                               but->pos--;
+                               but->pos -= step;
                                changed= 1;
                        }
                } 
@@ -1820,11 +1853,11 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                }
                                break;
                        case RIGHTARROWKEY:
-                               ui_textedit_move(but, data, 1, event->shift, event->ctrl);
+                               ui_textedit_move(but, data, 1, event->shift, event->ctrl, FALSE);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case LEFTARROWKEY:
-                               ui_textedit_move(but, data, 0, event->shift, event->ctrl);
+                               ui_textedit_move(but, data, 0, event->shift, event->ctrl, FALSE);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case DOWNARROWKEY:
@@ -1834,7 +1867,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                }
                                /* pass on purposedly */
                        case ENDKEY:
-                               ui_textedit_move_end(but, data, 1, event->shift);
+                               ui_textedit_move(but, data, 1, event->shift, TRUE, TRUE);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case UPARROWKEY:
@@ -1844,7 +1877,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                }
                                /* pass on purposedly */
                        case HOMEKEY:
-                               ui_textedit_move_end(but, data, 0, event->shift);
+                               ui_textedit_move(but, data, 0, event->shift, TRUE, TRUE);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case PADENTER:
@@ -1853,12 +1886,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                        case DELKEY:
-                               changed= ui_textedit_delete(but, data, 1, 0);
+                               changed= ui_textedit_delete(but, data, 1, 0, event->ctrl);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
 
                        case BACKSPACEKEY:
-                               changed= ui_textedit_delete(but, data, 0, event->shift);
+                               changed= ui_textedit_delete(but, data, 0, event->shift, event->ctrl);
                                retval= WM_UI_HANDLER_BREAK;
                                break;
                                
@@ -4049,6 +4082,88 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
        return WM_UI_HANDLER_CONTINUE;
 }
 
+static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data, int mx, int my, int shift)
+{
+       MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
+       int changed= 1;
+       float dx, dy;
+
+       dx = mx - data->draglastx;
+       dy = my - data->draglasty;
+
+       if(shift) {
+               dx /= 5.0f;
+               dy /= 5.0f;
+       }
+
+       if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
+                /* resize preview widget itself */
+               scopes->track_preview_height = (but->y2 - but->y1) + (data->dragstarty - my);
+       } else {
+               if(scopes->marker) {
+                       if(scopes->marker->framenr!=scopes->framenr)
+                               scopes->marker= BKE_tracking_ensure_marker(scopes->track, scopes->framenr);
+
+                       scopes->marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED);
+                       scopes->marker->pos[0]+= -dx*scopes->slide_scale[0] / (but->block->maxx-but->block->minx);
+                       scopes->marker->pos[1]+= -dy*scopes->slide_scale[1] / (but->block->maxy-but->block->miny);
+
+                       WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL);
+               }
+
+               scopes->ok= 0;
+       }
+
+       data->draglastx= mx;
+       data->draglasty= my;
+
+       return changed;
+}
+
+static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+       int mx, my;
+
+       mx= event->x;
+       my= event->y;
+       ui_window_to_block(data->region, block, &mx, &my);
+
+       if(data->state == BUTTON_STATE_HIGHLIGHT) {
+               if(event->type==LEFTMOUSE && event->val==KM_PRESS) {
+                       data->dragstartx= mx;
+                       data->dragstarty= my;
+                       data->draglastx= mx;
+                       data->draglasty= my;
+                       button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+                       /* also do drag the first time */
+                       if(ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift))
+                               ui_numedit_apply(C, block, but, data);
+
+                       return WM_UI_HANDLER_BREAK;
+               }
+       }
+       else if(data->state == BUTTON_STATE_NUM_EDITING) {
+               if(event->type == ESCKEY) {
+                       data->cancel= 1;
+                       data->escapecancel= 1;
+                       button_activate_state(C, but, BUTTON_STATE_EXIT);
+               }
+               else if(event->type == MOUSEMOVE) {
+                       if(mx!=data->draglastx || my!=data->draglasty) {
+                               if(ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift))
+                                       ui_numedit_apply(C, block, but, data);
+                       }
+               }
+               else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) {
+                       button_activate_state(C, but, BUTTON_STATE_EXIT);
+               }
+               return WM_UI_HANDLER_BREAK;
+       }
+
+       return WM_UI_HANDLER_CONTINUE;
+}
+
 static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
 {
        uiBut *but = (uiBut *)arg1;
@@ -4407,7 +4522,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
                /* check prevval because of modal operators [#24016],
                 * modifier check is to allow Ctrl+C for copy.
                 * if this causes other problems, remove this check and suffer the bug :) - campbell */
-               (event->prevval != KM_PRESS || ISKEYMODIFIER(event->prevtype))
+               ((event->prevval != KM_PRESS) || (ISKEYMODIFIER(event->prevtype)) || (event->type == EVT_DROP))
        ) {
                /* handle copy-paste */
                if(ELEM(event->type, CKEY, VKEY) && event->val==KM_PRESS && (event->ctrl || event->oskey)) {
@@ -4583,6 +4698,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
        case INLINK:
                retval= ui_do_but_LINK(C, but, data, event);
                break;
+       case TRACKPREVIEW:
+               retval= ui_do_but_TRACKPREVIEW(C, block, but, data, event);
+               break;
        }
        
        return retval;