merge with/from trunk at r35190
[blender.git] / source / blender / editors / interface / interface_handlers.c
index c548be947fa98b1295c198036ef62196de643b3a..a556d8322b24d059e1dcc8ebca6fd4ec7f94131b 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -38,6 +38,8 @@
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
 #include "PIL_time.h"
 
 #include "BKE_colortools.h"
@@ -324,18 +326,22 @@ static void ui_apply_autokey_undo(bContext *C, uiBut *but)
 {
        Scene *scene= CTX_data_scene(C);
        uiAfterFunc *after;
-       const char *str= NULL;
 
        if(but->flag & UI_BUT_UNDO) {
+               const char *str= NULL;
+
                /* define which string to use for undo */
                if ELEM(but->type, LINK, INLINK) str= "Add button link";
                else if ELEM(but->type, MENU, ICONTEXTROW) str= but->drawstr;
                else if(but->drawstr[0]) str= but->drawstr;
                else str= but->tip;
-       }
 
-       /* delayed, after all other funcs run, popups are closed, etc */
-       if(str) {
+               /* fallback, else we dont get an undo! */
+               if(str == NULL || str[0] == '\0') {
+                       str= "Unknown Action";
+               }
+
+               /* delayed, after all other funcs run, popups are closed, etc */
                after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
                BLI_strncpy(after->undostr, str, sizeof(after->undostr));
                BLI_addtail(&UIAfterFuncs, after);
@@ -646,13 +652,12 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event)
        return BLI_in_rcti(&rect, x, y);
 }
 
-#define UI_DRAG_THRESHOLD      3
 static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
        /* prevent other WM gestures to start while we try to drag */
        WM_gestures_remove(C);
 
-       if( ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > UI_DRAG_THRESHOLD ) {
+       if( ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > U.dragthreshold ) {
                wmDrag *drag;
                
                button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -3456,7 +3461,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
                if(event->type==LEFTMOUSE && event->val==KM_PRESS) {
                        CurveMapping *cumap= (CurveMapping*)but->poin;
                        CurveMap *cuma= cumap->cm+cumap->cur;
-                       CurveMapPoint *cmp= cuma->curve;
+                       CurveMapPoint *cmp;
                        float fx, fy, zoomx, zoomy, offsx, offsy;
                        float dist, mindist= 200.0f; // 14 pixels radius
                        int sel= -1;
@@ -3756,13 +3761,13 @@ static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int
        Scopes *scopes = (Scopes *)but->poin;
        rcti rect;
        int changed= 1;
-       float dx, dy;
+       /* float dx, dy; */
 
        rect.xmin= but->x1; rect.xmax= but->x2;
        rect.ymin= but->y1; rect.ymax= but->y2;
 
-       dx = mx - data->draglastx;
-       dy = my - data->draglasty;
+       /* dx = mx - data->draglastx; */
+       /* dy = my - data->draglasty; */
 
        if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
                 /* resize vectorscope widget itself */
@@ -3963,35 +3968,31 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
        uiBut *but = (uiBut *)arg1;
 
        if (but->optype) {
-               char buf[512], *butstr, *cpoin;
+               char buf[512], *cpoin;
 
                IDProperty *prop= (but->opptr)? but->opptr->data: NULL;
                
                /* complex code to change name of button */
                if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) {
                        wmKeyMap *km= NULL;
+                       char *butstr_orig;
 
-                       butstr= MEM_mallocN(strlen(but->str)+strlen(buf)+2, "menu_block_set_keymaps");
-                       
                        // XXX but->str changed... should not, remove the hotkey from it
                        cpoin= strchr(but->str, '|');
                        if(cpoin) *cpoin= 0;            
-                       
-                       strcpy(butstr, but->str);
-                       strcat(butstr, "|");
-                       strcat(butstr, buf);
-                       
+
+                       butstr_orig= BLI_strdup(but->str);
+                       BLI_snprintf(but->strdata, sizeof(but->strdata), "%s|%s", butstr_orig, buf);
+                       MEM_freeN(butstr_orig);
                        but->str= but->strdata;
-                       BLI_strncpy(but->str, butstr, sizeof(but->strdata));
-                       MEM_freeN(butstr);
-                       
+
                        ui_check_but(but);
-                       
+
                        /* set the keymap editable else the key wont save */
                        WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
                        WM_keymap_copy_to_user(km);
-                               
-               else {
+               }
+               else {
                        /* shortcut was removed */
                        cpoin= strchr(but->str, '|');
                        if(cpoin) *cpoin= 0;
@@ -4110,7 +4111,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
        button_timers_tooltip_remove(C, but);
 
        if(but->rnaprop)
-               name= (char*)RNA_property_ui_name(but->rnaprop);
+               name= RNA_property_ui_name(but->rnaprop);
        else if (but->optype)
                name= but->optype->name;
        else
@@ -4356,17 +4357,18 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
                /* reset to default */
                /* XXX hardcoded keymap check.... */
                else if(ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) {
+                       /* ctrl-0 = for arrays, only the active one gets done (vs whole array for just 0) */
                        if (!(ELEM3(but->type, HSVCIRCLE, HSVCUBE, HISTOGRAM)))
-                               ui_set_but_default(C, but);
+                               ui_set_but_default(C, but, !event->ctrl);
                }
                /* handle menu */
                else if(event->type == RIGHTMOUSE && event->val == KM_PRESS) {
                        /* RMB has two options now */
                        if (ui_but_menu(C, but)) {
                                return WM_UI_HANDLER_BREAK;
-                       }
                }
        }
+       }
 
        /* verify if we can edit this button */
        if(ELEM(event->type, LEFTMOUSE, RETKEY)) {
@@ -4679,19 +4681,21 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but)
        uiHandleButtonData *data;
 
        data= but->active;
+       if(data) {
 
-       if(data->tooltiptimer) {
-               WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
-               data->tooltiptimer= NULL;
-       }
-       if(data->tooltip) {
-               ui_tooltip_free(C, data->tooltip);
-               data->tooltip= NULL;
-       }
+               if(data->tooltiptimer) {
+                       WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
+                       data->tooltiptimer= NULL;
+               }
+               if(data->tooltip) {
+                       ui_tooltip_free(C, data->tooltip);
+                       data->tooltip= NULL;
+               }
 
-       if(data->autoopentimer) {
-               WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
-               data->autoopentimer= NULL;
+               if(data->autoopentimer) {
+                       WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
+                       data->autoopentimer= NULL;
+               }
        }
 }
 
@@ -5233,8 +5237,15 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
                retval= WM_UI_HANDLER_CONTINUE;
        }
        else if(data->state == BUTTON_STATE_MENU_OPEN) {
+               /* check for exit because of mouse-over another button */
                switch(event->type) {
-                       case MOUSEMOVE: {
+                       case MOUSEMOVE:
+                               
+                               if(data->menu && data->menu->region)
+                                       if(ui_mouse_inside_region(data->menu->region, event->x, event->y))
+                                               break;
+                       
+                       {
                                uiBut *bt= ui_but_find_mouse_over(ar, event->x, event->y);
 
                                if(bt && bt->active != data) {
@@ -5457,7 +5468,7 @@ static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *men
        return menu->dotowards;
 }
 
-int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int UNUSED(topmenu))
+static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int UNUSED(topmenu))
 {
        ARegion *ar;
        uiBlock *block;
@@ -5678,7 +5689,6 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
                                                (event->ctrl == FALSE) &&
                                                (event->oskey == FALSE)
                                        ) {
-                                               count= 0;
                                                for(but= block->buttons.first; but; but= but->next) {
 
                                                        if(but->menu_key==event->type) {
@@ -5718,7 +5728,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
 
                                if(ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) && event->val==KM_PRESS) {
                                        if(saferct && !BLI_in_rctf(&saferct->parent, event->x, event->y)) {
-                                               if(block->flag & (UI_BLOCK_OUT_1|UI_BLOCK_KEEP_OPEN))
+                                               if(block->flag & (UI_BLOCK_OUT_1))
                                                        menu->menuretval= UI_RETURN_OK;
                                                else
                                                        menu->menuretval= UI_RETURN_OUT;
@@ -5759,7 +5769,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
 
                                        /* strict check, and include the parent rect */
                                        if(!menu->dotowards && !saferct) {
-                                               if(block->flag & (UI_BLOCK_OUT_1|UI_BLOCK_KEEP_OPEN))
+                                               if(block->flag & (UI_BLOCK_OUT_1))
                                                        menu->menuretval= UI_RETURN_OK;
                                                else
                                                        menu->menuretval= UI_RETURN_OUT;