remove unused includes
[blender.git] / source / blender / editors / interface / interface_handlers.c
index ff56b14c653c26b69543b992367598cda66981ac..e1a760628b05b090605ef7dc62f28f23a049c3d2 100644 (file)
  */
 
 #include <float.h>
+#include <limits.h>
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 #include "MEM_guardedalloc.h"
 
@@ -42,7 +44,6 @@
 #include "BKE_idprop.h"
 #include "BKE_report.h"
 #include "BKE_texture.h"
-#include "BKE_utildefines.h"
 
 #include "ED_screen.h"
 #include "ED_util.h"
@@ -176,6 +177,7 @@ typedef struct uiAfterFunc {
        int autokey;
 } uiAfterFunc;
 
+static int ui_but_contains_pt(uiBut *but, int mx, int my);
 static int ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y);
 static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
 static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata);
@@ -184,11 +186,16 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but);
 
 /* ******************** menu navigation helpers ************** */
 
+static int ui_but_editable(uiBut *but)
+{
+       return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR);
+}
+
 static uiBut *ui_but_prev(uiBut *but)
 {
        while(but->prev) {
                but= but->prev;
-               if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
+               if(!ui_but_editable(but)) return but;
        }
        return NULL;
 }
@@ -197,7 +204,7 @@ static uiBut *ui_but_next(uiBut *but)
 {
        while(but->next) {
                but= but->next;
-               if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
+               if(!ui_but_editable(but)) return but;
        }
        return NULL;
 }
@@ -208,7 +215,7 @@ static uiBut *ui_but_first(uiBlock *block)
        
        but= block->buttons.first;
        while(but) {
-               if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
+               if(!ui_but_editable(but)) return but;
                but= but->next;
        }
        return NULL;
@@ -220,7 +227,7 @@ static uiBut *ui_but_last(uiBlock *block)
        
        but= block->buttons.last;
        while(but) {
-               if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
+               if(!ui_but_editable(but)) return but;
                but= but->prev;
        }
        return NULL;
@@ -229,7 +236,7 @@ static uiBut *ui_but_last(uiBlock *block)
 static int ui_is_a_warp_but(uiBut *but)
 {
        if(U.uiflag & USER_CONTINUOUS_MOUSE)
-               if(ELEM(but->type, NUM, NUMABS))
+               if(ELEM3(but->type, NUM, NUMABS, HSVCIRCLE))
                        return TRUE;
 
        return FALSE;
@@ -1148,7 +1155,7 @@ static int ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
        int len= strlen(str);
        int change= 0;
        if(but->selsta != but->selend && len) {
-               memmove( str+but->selsta, str+but->selend, len+1 );
+               memmove( str+but->selsta, str+but->selend, len-but->selsta+1 );
                change= 1;
        }
        
@@ -1528,6 +1535,19 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
        data->str= MEM_callocN(sizeof(char)*data->maxlen + 1, "textedit str");
        ui_get_but_string(but, data->str, data->maxlen);
 
+       if(ELEM3(but->type, NUM, NUMABS, NUMSLI)) {
+               /* XXX: we dont have utf editing yet so for numbers its best to strip out utf chars 
+                * this is so the deg' synbol isnt included in number editing fields: bug 22274 */
+               int i;
+               for(i=0; data->str[i]; i++) {
+                       if(!isascii(data->str[i])) {
+                               data->str[i]= '\0';
+                               break;
+                       }
+               }
+       }
+       
+       
        data->origstr= BLI_strdup(data->str);
        data->selextend= 0;
        data->selstartx= 0;
@@ -1654,7 +1674,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                my= event->y;
                                ui_window_to_block(data->region, block, &mx, &my);
 
-                               if ((but->y1 <= my) && (my <= but->y2) && (but->x1 <= mx) && (mx <= but->x2)) {
+                               if (ui_but_contains_pt(but, mx, my)) {
                                        ui_textedit_set_cursor_pos(but, data, mx);
                                        but->selsta = but->selend = but->pos;
                                        data->selstartx= mx;
@@ -1994,14 +2014,17 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
                if(event->type == MOUSEMOVE)
                        return WM_UI_HANDLER_CONTINUE;
                
-               if(event->type == ESCKEY) {
-                       /* data->cancel doesnt work, this button opens immediate */
-                       if(but->flag & UI_BUT_IMMEDIATE)
-                               ui_set_but_val(but, 0);
-                       else
-                               data->cancel= 1;
-                       button_activate_state(C, but, BUTTON_STATE_EXIT);
-                       return WM_UI_HANDLER_BREAK;
+               if(event->type == LEFTMOUSE && event->val==KM_PRESS) {
+                       /* only cancel if click outside the button */
+                       if(ui_mouse_inside_button(but->active->region, but, event->x, event->y) == 0) {
+                               /* data->cancel doesnt work, this button opens immediate */
+                               if(but->flag & UI_BUT_IMMEDIATE)
+                                       ui_set_but_val(but, 0);
+                               else
+                                       data->cancel= 1;
+                               button_activate_state(C, but, BUTTON_STATE_EXIT);
+                               return WM_UI_HANDLER_BREAK;
+                       }
                }
                
                /* always set */
@@ -2035,15 +2058,11 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
        return WM_UI_HANDLER_CONTINUE;
 }
 
-
 static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
        if(data->state == BUTTON_STATE_HIGHLIGHT) {
                if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) {
-                       short event= (short)ui_get_but_val(but);
-                       /* hardcoded prevention from editing or assigning ESC */
-                       if(event!=ESCKEY)
-                               button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
+                       button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
                        return WM_UI_HANDLER_BREAK;
                }
        }
@@ -2052,7 +2071,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, w
                        return WM_UI_HANDLER_CONTINUE;
 
                if(event->val==KM_PRESS) {
-                       if(event->type!=ESCKEY && WM_key_event_string(event->type)[0])
+                       if(WM_key_event_string(event->type)[0])
                                ui_set_but_val(but, event->type);
                        else
                                data->cancel= 1;
@@ -2119,8 +2138,13 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
                }
                
                if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) {
+                       int ret = WM_UI_HANDLER_BREAK;
+                       /* XXX (a bit ugly) Special case handling for filebrowser drag button */
+                       if(but->dragpoin && but->imb && ui_but_mouse_inside_icon(but, data->region, event)) {
+                               ret = WM_UI_HANDLER_CONTINUE;
+                       }
                        button_activate_state(C, but, BUTTON_STATE_EXIT);
-                       return WM_UI_HANDLER_BREAK;
+                       return ret;
                }
        }
        else if(data->state == BUTTON_STATE_WAIT_DRAG) {
@@ -2213,7 +2237,6 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
        softmax= but->softmax;
        softrange= softmax - softmin;
 
-
        if(ui_is_a_warp_but(but)) {
                /* Mouse location isn't screen clamped to the screen so use a linear mapping
                 * 2px == 1-int, or 1px == 1-ClickStep */
@@ -2273,15 +2296,18 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
                /* Use a non-linear mapping of the mouse drag especially for large floats (normal behavior) */
                deler= 500;
                if(!ui_is_but_float(but)) {
-                       if((softrange)<100) deler= 200.0;
-                       if((softrange)<25) deler= 50.0;
+                       /* prevent large ranges from getting too out of control */
+                       if (softrange > 600) deler = powf(softrange, 0.75);
+                       
+                       if (softrange < 100) deler= 200.0;
+                       if (softrange < 25) deler= 50.0;
                }
                deler /= fac;
 
-               if(ui_is_but_float(but) && softrange > 11) {
+               if(softrange > 11) {
                        /* non linear change in mouse input- good for high precicsion */
                        data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002);
-               } else if (!ui_is_but_float(but) && softrange > 129) { /* only scale large int buttons */
+               } else if (softrange > 129) { /* only scale large int buttons */
                        /* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
                        data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004);
                } else {
@@ -2289,8 +2315,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
                        data->dragf+= ((float)(mx-data->draglastx))/deler ;
                }
        
-               if(data->dragf>1.0) data->dragf= 1.0;
-               if(data->dragf<0.0) data->dragf= 0.0;
+               CLAMP(data->dragf, 0.0, 1.0);
                data->draglastx= mx;
                tempf= (softmin + data->dragf*softrange);
 
@@ -2302,7 +2327,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
 
                        CLAMP(temp, softmin, softmax);
                        lvalue= (int)data->value;
-
+                       
                        if(temp != lvalue) {
                                data->dragchange= 1;
                                data->value= (double)temp;
@@ -3035,7 +3060,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
        return WM_UI_HANDLER_CONTINUE;
 }
 
-static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx, int my)
+static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx, int my, int shift)
 {
        rcti rect;
        int changed= 1;
@@ -3049,13 +3074,29 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx
        
        /* exception, when using color wheel in 'locked' value state:
         * allow choosing a hue for black values, by giving a tiny increment */
-       if (but->a2 == 1) { // lock
+       if (but->flag & UI_BUT_COLOR_LOCK) { // lock
                if (hsv[2] == 0.f) hsv[2] = 0.0001f;
        }
-               
+
+       if(U.uiflag & USER_CONTINUOUS_MOUSE) {
+               float fac= shift ? 0.05 : 1.0f;
+               /* slow down the mouse, this is fairly picky */
+               mx = (data->dragstartx*(1.0f-fac) + mx*fac);
+               my = (data->dragstarty*(1.0f-fac) + my*fac);
+       }
+
        ui_hsvcircle_vals_from_pos(hsv, hsv+1, &rect, (float)mx, (float)my);
-       
+
+       if(but->flag & UI_BUT_COLOR_CUBIC)
+               hsv[1]= 1.0f - sqrt3f(1.0f - hsv[1]);
+
        hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
+
+       if((but->flag & UI_BUT_VEC_SIZE_LOCK) && (rgb[0] || rgb[1] || rgb[2])) {
+               normalize_v3(rgb);
+               mul_v3_fl(rgb, but->a2);
+       }
+
        ui_set_but_vectorf(but, rgb);
        
        data->draglastx= mx;
@@ -3082,7 +3123,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
                        button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
                        
                        /* also do drag the first time */
-                       if(ui_numedit_but_HSVCIRCLE(but, data, mx, my))
+                       if(ui_numedit_but_HSVCIRCLE(but, data, mx, my, event->shift))
                                ui_numedit_apply(C, block, but, data);
                        
                        return WM_UI_HANDLER_BREAK;
@@ -3133,7 +3174,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
                }
                else if(event->type == MOUSEMOVE) {
                        if(mx!=data->draglastx || my!=data->draglasty) {
-                               if(ui_numedit_but_HSVCIRCLE(but, data, mx, my))
+                               if(ui_numedit_but_HSVCIRCLE(but, data, mx, my, event->shift))
                                        ui_numedit_apply(C, block, but, data);
                        }
                }
@@ -3209,24 +3250,8 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle
 
                        if(event->ctrl) {
                                /* insert new key on mouse location */
-                               if(coba->tot < MAXCOLORBAND-1) {
-                                       float pos= ((float)(mx - but->x1))/(but->x2-but->x1);
-                                       float col[4];
-                                       
-                                       do_colorband(coba, pos, col);   /* executes it */
-                                       
-                                       coba->tot++;
-                                       coba->cur= coba->tot-1;
-                                       
-                                       coba->data[coba->cur].r= col[0];
-                                       coba->data[coba->cur].g= col[1];
-                                       coba->data[coba->cur].b= col[2];
-                                       coba->data[coba->cur].a= col[3];
-                                       coba->data[coba->cur].pos= pos;
-
-                                       ui_colorband_update(coba);
-                               }
-
+                               float pos= ((float)(mx - but->x1))/(but->x2-but->x1);
+                               colorband_element_add(coba, pos);
                                button_activate_state(C, but, BUTTON_STATE_EXIT);
                        }
                        else {
@@ -4308,6 +4333,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
        case ROW:
        case LISTROW:
        case BUT_IMAGE:
+       case PROGRESSBAR:
                retval= ui_do_but_EXIT(C, but, data, event);
                break;
        case HISTOGRAM:
@@ -5163,7 +5189,8 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
                        button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
                }
                else {
-                       if(event->type != MOUSEMOVE) {
+                       if (ISKEYBOARD(event->type)) {
+                               /* keyboard menu hierarchy navigation, going back to previous level */
                                but->active->used_mouse= 0;
                                button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
                        }