diff options
Diffstat (limited to 'source/blender/editors/interface/interface_handlers.c')
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 405 |
1 files changed, 277 insertions, 128 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b8a84e1638a..593744f01e0 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -78,6 +78,9 @@ #include "WM_api.h" #include "WM_types.h" +/* place the mouse at the scaled down location when un-grabbing */ +#define USE_CONT_MOUSE_CORRECT + /* proto */ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to); static void ui_add_link(bContext *C, uiBut *from, uiBut *to); @@ -152,6 +155,12 @@ typedef struct uiHandleButtonData { float dragf, dragfstart; CBData *dragcbd; +#ifdef USE_CONT_MOUSE_CORRECT + /* when ungrabbing buttons which are #ui_is_a_warp_but(), we may want to position them + * FLT_MAX signifies do-nothing, use #ui_block_to_window_fl() to get this into a usable space */ + float ungrab_mval[2]; +#endif + /* menu open (watch uiFreeActiveButtons) */ uiPopupBlockHandle *menu; int menuretval; @@ -697,10 +706,10 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event) if (but->imb) ; /* use button size itself */ else if (but->flag & UI_ICON_LEFT) { - rect.xmax = rect.xmin + (BLI_RCT_SIZE_Y(&rect)); + rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect)); } else { - int delta = BLI_RCT_SIZE_X(&rect) - BLI_RCT_SIZE_Y(&rect); + int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect); rect.xmin += delta / 2; rect.xmax -= delta / 2; } @@ -721,7 +730,7 @@ static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but)); if (but->imb) - WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_RCT_SIZE_X(&but->rect), BLI_RCT_SIZE_Y(&but->rect)); + WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)); return 1; } @@ -808,6 +817,8 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to) uiLink *link = from->link; + PointerRNA props_ptr, object_ptr; + if (link->ppoin) sens_from_links = (bController ***)(link->ppoin); else return; @@ -836,9 +847,15 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to) /* only works if the sensor and the actuator are from the same object */ if (!act_iter) return; + + /* in case the linked controller is not the active one */ + RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); + + WM_operator_properties_create(&props_ptr, "LOGIC_OT_controller_add"); + RNA_string_set(&props_ptr, "object", ob->id.name+2); /* (3) add a new controller */ - if (WM_operator_name_call(C, "LOGIC_OT_controller_add", WM_OP_EXEC_DEFAULT, NULL) & OPERATOR_FINISHED) { + if (WM_operator_name_call(C, "LOGIC_OT_controller_add", WM_OP_EXEC_DEFAULT, &props_ptr) & OPERATOR_FINISHED) { cont = (bController *)ob->controllers.last; cont->type = CONT_LOGIC_AND; /* Quick fix to make sure we always have an AND controller. It might be nicer to make sure the operator gives us the right one though... */ @@ -858,6 +875,7 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to) MEM_freeN(tmp_but->link); MEM_freeN(tmp_but); } + WM_operator_properties_free(&props_ptr); } static void ui_add_link(bContext *C, uiBut *from, uiBut *to) @@ -1309,7 +1327,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho /* XXX solve generic */ if (but->type == NUM || but->type == NUMSLI) - startx += (int)(0.5f * (BLI_RCT_SIZE_Y(&but->rect))); + startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect))); else if (ELEM(but->type, TEX, SEARCH_MENU)) { startx += 5; if (but->flag & UI_HAS_ICON) @@ -1386,13 +1404,13 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, short x) { - if (x > data->selstartx) data->selextend = EXTEND_RIGHT; + if (x > data->selstartx) data->selextend = EXTEND_RIGHT; else if (x < data->selstartx) data->selextend = EXTEND_LEFT; ui_textedit_set_cursor_pos(but, data, x); - if (data->selextend == EXTEND_RIGHT) but->selend = but->pos; - if (data->selextend == EXTEND_LEFT) but->selsta = but->pos; + if (data->selextend == EXTEND_RIGHT) but->selend = but->pos; + else if (data->selextend == EXTEND_LEFT) but->selsta = but->pos; ui_check_but(but); } @@ -1596,6 +1614,7 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste /* paste */ if (paste) { + /* TODO, ensure UTF8 ui_is_but_utf8() - campbell */ /* extract the first line from the clipboard */ p = pbuf = WM_clipboard_text_get(0); @@ -1955,8 +1974,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle if (changed) { /* only update when typing for TAB key */ - if (update && data->interactive) ui_apply_button(C, block, but, data, 1); - else ui_check_but(but); + if (update && data->interactive) { + ui_apply_button(C, block, but, data, 1); + } + else { + ui_check_but(but); + } but->changed = TRUE; if (data->searchbox) @@ -2047,8 +2070,12 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data) static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) { - if (data->interactive) ui_apply_button(C, block, but, data, 1); - else ui_check_but(but); + if (data->interactive) { + ui_apply_button(C, block, but, data, 1); + } + else { + ui_check_but(but); + } ED_region_tag_redraw(data->region); } @@ -2373,14 +2400,14 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa } if (snap == 1) { - if (softrange < 2.10f) tempf = 0.1f * floorf(10.0f * tempf); + if (softrange < 2.10f) tempf = 0.1f * floorf(10.0f * tempf); else if (softrange < 21.0f) tempf = floorf(tempf); - else tempf = 10.0f * floorf(tempf / 10.0f); + else tempf = 10.0f * floorf(tempf / 10.0f); } else if (snap == 2) { - if (softrange < 2.10f) tempf = 0.01f * floorf(100.0f * tempf); - else if (softrange < 21.0f) tempf = 0.1f * floorf(10.0f * tempf); - else tempf = floor(tempf); + if (softrange < 2.10f) tempf = 0.01f * floorf(100.0f * tempf); + else if (softrange < 21.0f) tempf = 0.1f * floorf(10.0f * tempf); + else tempf = floor(tempf); } if (fac != 1.0f) @@ -2459,9 +2486,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i } } else { - if (softrange > 256) fac = 1.0; /* 1px == 1 */ - else if (softrange > 32) fac = 1.0 / 2.0; /* 2px == 1 */ - else fac = 1.0 / 16.0; /* 16px == 1? */ + if (softrange > 256) fac = 1.0; /* 1px == 1 */ + else if (softrange > 32) fac = 1.0 / 2.0; /* 2px == 1 */ + else fac = 1.0 / 16.0; /* 16px == 1? */ temp = data->startvalue + (((double)mx - data->dragstartx) * (double)fac); temp = ui_numedit_apply_snap(temp, softmin, softmax, snap); @@ -2493,10 +2520,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i deler = 500; if (!ui_is_but_float(but)) { /* 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; + if (softrange > 600) deler = powf(softrange, 0.75); + else if (softrange < 100) deler = 200.0; + else if (softrange < 25) deler = 50.0; } deler /= fac; @@ -2582,8 +2608,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval = WM_UI_HANDLER_BREAK; } - else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) + else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) { click = 1; + } else if (event->type == MINUSKEY && event->val == KM_PRESS) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); data->value = -data->value; @@ -2611,7 +2638,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton fac = 1.0f; if (event->shift) fac /= 10.0f; - if (event->alt) fac /= 20.0f; + if (event->alt) fac /= 20.0f; snap = (event->ctrl) ? (event->shift) ? 2 : 1 : 0; @@ -2639,7 +2666,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton softmax = but->softmax; if (!ui_is_but_float(but)) { - if (mx < (but->rect.xmin + BLI_RCT_SIZE_X(&but->rect) / 3 - 3)) { + if (mx < (but->rect.xmin + BLI_rctf_size_x(&but->rect) / 3 - 3)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); temp = (int)data->value - 1; @@ -2650,7 +2677,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_EXIT); } - else if (mx > (but->rect.xmin + (2 * BLI_RCT_SIZE_X(&but->rect) / 3) + 3)) { + else if (mx > (but->rect.xmin + (2 * BLI_rctf_size_x(&but->rect) / 3) + 3)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); temp = (int)data->value + 1; @@ -2661,11 +2688,12 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_EXIT); } - else + else { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); + } } else { - if (mx < (but->rect.xmin + BLI_RCT_SIZE_X(&but->rect) / 3 - 3)) { + if (mx < (but->rect.xmin + BLI_rctf_size_x(&but->rect) / 3 - 3)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); tempf = (float)data->value - 0.01f * but->a1; @@ -2674,7 +2702,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_EXIT); } - else if (mx > but->rect.xmin + (2 * (BLI_RCT_SIZE_X(&but->rect) / 3) + 3)) { + else if (mx > but->rect.xmin + (2 * (BLI_rctf_size_x(&but->rect) / 3) + 3)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); tempf = (float)data->value + 0.01f * but->a1; @@ -2683,8 +2711,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_EXIT); } - else + else { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); + } } retval = WM_UI_HANDLER_BREAK; @@ -2702,14 +2731,20 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short softmax = but->softmax; softrange = softmax - softmin; - if (but->type == NUMSLI) deler = (BLI_RCT_SIZE_X(&but->rect) - 5.0f * but->aspect); - else if (but->type == HSVSLI) deler = (BLI_RCT_SIZE_X(&but->rect) / 2.0f - 5.0f * but->aspect); + if (but->type == NUMSLI) { + deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect); + } + else if (but->type == HSVSLI) { + deler = (BLI_rctf_size_x(&but->rect) / 2.0f - 5.0f * but->aspect); + } else if (but->type == SCROLL) { - int horizontal = (BLI_RCT_SIZE_X(&but->rect) > BLI_RCT_SIZE_Y(&but->rect)); - float size = (horizontal) ? BLI_RCT_SIZE_X(&but->rect) : -BLI_RCT_SIZE_Y(&but->rect); + int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect)); + float size = (horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect); deler = size * (but->softmax - but->softmin) / (but->softmax - but->softmin + but->a1); } - else deler = (BLI_RCT_SIZE_X(&but->rect) - 5.0f * but->aspect); + else { + deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect); + } f = (float)(mx - data->dragstartx) / deler + data->dragfstart; @@ -2721,19 +2756,21 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short temp = floorf(tempf + 0.5f); if (ctrl) { - if (tempf == softmin || tempf == softmax) ; + if (tempf == softmin || tempf == softmax) { + /* pass */ + } else if (ui_is_but_float(but)) { if (shift) { - if (tempf == softmin || tempf == softmax) ; + if (tempf == softmin || tempf == softmax) {} else if (softmax - softmin < 2.10f) tempf = 0.01f * floorf(100.0f * tempf); - else if (softmax - softmin < 21.0f) tempf = 0.1f * floorf(10.0f * tempf); - else tempf = floorf(tempf); + else if (softmax - softmin < 21.0f) tempf = 0.1f * floorf(10.0f * tempf); + else tempf = floorf(tempf); } else { - if (softmax - softmin < 2.10f) tempf = 0.1f * floorf(10.0f * tempf); + if (softmax - softmin < 2.10f) tempf = 0.1f * floorf(10.0f * tempf); else if (softmax - softmin < 21.0f) tempf = floorf(tempf); - else tempf = 10.0f * floorf(tempf / 10.0f); + else tempf = 10.0f * floorf(tempf / 10.0f); } } else { @@ -2792,7 +2829,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } /* alt-click on sides to get "arrows" like in NUM buttons, and match wheel usage above */ else if (event->type == LEFTMOUSE && event->alt) { - int halfpos = BLI_RCT_CENTER_X(&but->rect); + int halfpos = BLI_rctf_cent_x(&but->rect); click = 2; if (mx < halfpos) mx = but->rect.xmin; @@ -2805,8 +2842,9 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval = WM_UI_HANDLER_BREAK; } - else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) + else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) { click = 1; + } else if (event->type == MINUSKEY && event->val == KM_PRESS) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); data->value = -data->value; @@ -2859,12 +2897,12 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton #if 0 if (but->type == SLI) { - f = (float)(mx - but->rect.xmin) / (BLI_RCT_SIZE_X(&but->rect)); /* same as below */ + f = (float)(mx - but->rect.xmin) / (BLI_rctf_size_x(&but->rect)); /* same as below */ } else #endif { - f = (float)(mx - but->rect.xmin) / (BLI_RCT_SIZE_X(&but->rect)); + f = (float)(mx - but->rect.xmin) / (BLI_rctf_size_x(&but->rect)); } f = softmin + f * softrange; @@ -2905,7 +2943,7 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut { int mx, my /*, click= 0 */; int retval = WM_UI_HANDLER_CONTINUE; - int horizontal = (BLI_RCT_SIZE_X(&but->rect) > BLI_RCT_SIZE_Y(&but->rect)); + int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect)); mx = event->x; my = event->y; @@ -3063,7 +3101,7 @@ static int ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, i * else we'll get a harmless but annoying jump when first clicking */ fp = data->origvec; - rad = BLI_RCT_SIZE_X(&but->rect); + rad = BLI_rctf_size_x(&but->rect); radsq = rad * rad; if (fp[2] > 0.0f) { @@ -3076,7 +3114,9 @@ static int ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, i mdx = 2.0f * mrad * fp[0] - (rad * fp[0]); mdy = 2.0f * mrad * fp[1] - (rad * fp[1]); } - else mdx = mdy = 0; + else { + mdx = mdy = 0; + } dx = (float)(mx + mdx - data->dragstartx); dy = (float)(my + mdy - data->dragstarty); @@ -3140,8 +3180,9 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut ui_numedit_apply(C, block, but, data); } } - else if (event->type == LEFTMOUSE && event->val != KM_PRESS) + else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { button_activate_state(C, but, BUTTON_STATE_EXIT); + } return WM_UI_HANDLER_BREAK; } @@ -3160,19 +3201,30 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); +#ifdef USE_CONT_MOUSE_CORRECT + if (ui_is_a_warp_but(but)) { + /* OK but can go outside bounds */ + data->ungrab_mval[0] = mx_fl; + data->ungrab_mval[1] = my_fl; + BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval); + } +#endif + if (but->rnaprop) { if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) - color_profile = BLI_PR_NONE; + color_profile = FALSE; } ui_get_but_vectorf(but, rgb); - rgb_to_hsv_compat_v(rgb, hsv); + if (color_profile && (int)but->a1) + ui_block_to_display_space_v3(but->block, rgb); + rgb_to_hsv_compat_v(rgb, hsv); /* relative position within box */ - x = ((float)mx_fl - but->rect.xmin) / BLI_RCT_SIZE_X(&but->rect); - y = ((float)my_fl - but->rect.ymin) / BLI_RCT_SIZE_Y(&but->rect); + x = ((float)mx_fl - but->rect.xmin) / BLI_rctf_size_x(&but->rect); + y = ((float)my_fl - but->rect.ymin) / BLI_rctf_size_y(&but->rect); CLAMP(x, 0.0f, 1.0f); CLAMP(y, 0.0f, 1.0f); @@ -3204,17 +3256,16 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, /* exception only for value strip - use the range set in but->min/max */ hsv[2] = y * (but->softmax - but->softmin) + but->softmin; - if (color_profile) - hsv[2] = srgb_to_linearrgb(hsv[2]); - - if (hsv[2] > but->softmax) - hsv[2] = but->softmax; break; default: assert(!"invalid hsv type"); } hsv_to_rgb_v(hsv, rgb); + + if (color_profile && (int)but->a1) + ui_block_to_scene_linear_v3(but->block, rgb); + copy_v3_v3(data->vec, rgb); data->draglastx = mx; @@ -3233,10 +3284,14 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF if (but->rnaprop) { if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) - color_profile = BLI_PR_NONE; + color_profile = FALSE; } ui_get_but_vectorf(but, rgb); + + if (color_profile && (int)but->a1) + ui_block_to_display_space_v3(but->block, rgb); + rgb_to_hsv_compat_v(rgb, hsv); switch ((int)but->a1) { @@ -3267,15 +3322,16 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF /* exception only for value strip - use the range set in but->min/max */ hsv[2] += ndof->rx * sensitivity; - if (color_profile) - hsv[2] = srgb_to_linearrgb(hsv[2]); - CLAMP(hsv[2], but->softmin, but->softmax); default: assert(!"invalid hsv type"); } - + hsv_to_rgb_v(hsv, rgb); + + if (color_profile && (int)but->a1) + ui_block_to_scene_linear_v3(but->block, rgb); + copy_v3_v3(data->vec, rgb); ui_set_but_vectorf(but, data->vec); } @@ -3358,8 +3414,9 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu ui_numedit_apply(C, block, but, data); } } - else if (event->type == LEFTMOUSE && event->val != KM_PRESS) + else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { button_activate_state(C, but, BUTTON_STATE_EXIT); + } return WM_UI_HANDLER_BREAK; } @@ -3377,6 +3434,22 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); +#ifdef USE_CONT_MOUSE_CORRECT + if (ui_is_a_warp_but(but)) { + /* OK but can go outside bounds */ + data->ungrab_mval[0] = mx_fl; + data->ungrab_mval[1] = my_fl; + { /* clamp */ + const float radius = minf(BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)) / 2.0f; + const float cent[2] = {BLI_rctf_cent_x(&but->rect), BLI_rctf_cent_y(&but->rect)}; + const float len = len_v2v2(cent, data->ungrab_mval); + if (len > radius) { + dist_ensure_v2_v2fl(data->ungrab_mval, cent, radius); + } + } + } +#endif + BLI_rcti_rctf_copy(&rect, &but->rect); ui_get_but_vectorf(but, rgb); @@ -3569,7 +3642,7 @@ static int ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx if (data->draglastx == mx) return changed; - dx = ((float)(mx - data->draglastx)) / BLI_RCT_SIZE_X(&but->rect); + dx = ((float)(mx - data->draglastx)) / BLI_rctf_size_x(&but->rect); data->dragcbd->pos += dx; CLAMP(data->dragcbd->pos, 0.0f, 1.0f); @@ -3598,7 +3671,7 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle if (event->ctrl) { /* insert new key on mouse location */ - float pos = ((float)(mx - but->rect.xmin)) / BLI_RCT_SIZE_X(&but->rect); + float pos = ((float)(mx - but->rect.xmin)) / BLI_rctf_size_x(&but->rect); colorband_element_add(coba, pos); button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -3610,7 +3683,7 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle /* activate new key when mouse is close */ for (a = 0, cbd = coba->data; a < coba->tot; a++, cbd++) { - xco = but->rect.xmin + (cbd->pos * BLI_RCT_SIZE_X(&but->rect)); + xco = but->rect.xmin + (cbd->pos * BLI_rctf_size_x(&but->rect)); xco = ABS(xco - mx); if (a == coba->cur) xco += 5; // selected one disadvantage if (xco < mindist) { @@ -3633,8 +3706,9 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle ui_numedit_apply(C, block, but, data); } } - else if (event->type == LEFTMOUSE && event->val != KM_PRESS) + else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { button_activate_state(C, but, BUTTON_STATE_EXIT); + } return WM_UI_HANDLER_BREAK; } @@ -3651,8 +3725,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap, float fx, fy, zoomx, zoomy /*, offsx, offsy */ /* UNUSED */; int a, changed = 0; - zoomx = BLI_RCT_SIZE_X(&but->rect) / BLI_RCT_SIZE_X(&cumap->curr); - zoomy = BLI_RCT_SIZE_Y(&but->rect) / BLI_RCT_SIZE_Y(&cumap->curr); + zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr); + zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr); /* offsx= cumap->curr.xmin; */ /* offsy= cumap->curr.ymin; */ @@ -3667,9 +3741,10 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap, } if (data->dragsel != -1) { + CurveMapPoint *cmp_last = NULL; const float mval_factor = ui_mouse_scale_warp_factor(shift); int moved_point = 0; /* for ctrl grid, can't use orig coords because of sorting */ - + fx = (mx - data->draglastx) / zoomx; fy = (my - data->draglasty) / zoomy; @@ -3687,6 +3762,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap, } if (cmp[a].x != origx || cmp[a].y != origy) moved_point = 1; + + cmp_last = &cmp[a]; } } @@ -3696,6 +3773,18 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap, data->draglastx = mx; data->draglasty = my; changed = 1; + +#ifdef USE_CONT_MOUSE_CORRECT + /* note: using 'cmp_last' is weak since there may be multiple points selected, + * but in practice this isnt really an issue */ + if (ui_is_a_warp_but(but)) { + /* OK but can go outside bounds */ + data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx); + data->ungrab_mval[1] = but->rect.ymin + ((cmp_last->y - cumap->curr.ymin) * zoomy); + BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval); + } +#endif + } data->dragchange = 1; /* mark for selection */ @@ -3747,8 +3836,8 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt float dist, mindist = 200.0f; // 14 pixels radius int sel = -1; - zoomx = BLI_RCT_SIZE_X(&but->rect) / BLI_RCT_SIZE_X(&cumap->curr); - zoomy = BLI_RCT_SIZE_Y(&but->rect) / BLI_RCT_SIZE_Y(&cumap->curr); + zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr); + zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr); offsx = cumap->curr.xmin; offsy = cumap->curr.ymin; @@ -3812,12 +3901,14 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt /* ok, we move a point */ /* deselect all if this one is deselect. except if we hold shift */ if (event->shift == FALSE) { - for (a = 0; a < cuma->totpoint; a++) + for (a = 0; a < cuma->totpoint; a++) { cmp[a].flag &= ~CUMA_SELECT; + } cmp[sel].flag |= CUMA_SELECT; } - else + else { cmp[sel].flag ^= CUMA_SELECT; + } } else { /* move the view */ @@ -3893,7 +3984,7 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) { /* resize histogram widget itself */ - hist->height = BLI_RCT_SIZE_Y(&but->rect) + (data->dragstarty - my); + hist->height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my); } else { /* scale histogram values (dy / 10 for better control) */ @@ -3977,7 +4068,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) { /* resize waveform widget itself */ - scopes->wavefrm_height = BLI_RCT_SIZE_Y(&but->rect) + (data->dragstarty - my); + scopes->wavefrm_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my); } else { /* scale waveform values */ @@ -4059,7 +4150,7 @@ static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) { /* resize vectorscope widget itself */ - scopes->vecscope_height = BLI_RCT_SIZE_Y(&but->rect) + (data->dragstarty - my); + scopes->vecscope_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my); } data->draglastx = mx; @@ -4129,8 +4220,8 @@ static int ui_do_but_CHARTAB(bContext *UNUSED(C), uiBlock *UNUSED(block), uiBut if (data->state == BUTTON_STATE_HIGHLIGHT) { if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) { /* Calculate the size of the button */ - width = abs(BLI_RCT_SIZE_X(&but->rect)); - height = abs(BLI_RCT_SIZE_Y(&but->rect)); + width = abs(BLI_rctf_size_x(&but->rect)); + height = abs(BLI_rctf_size_y(&but->rect)); butw = floor(width / 12); buth = floor(height / 6); @@ -4262,7 +4353,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) { /* resize preview widget itself */ - scopes->track_preview_height = BLI_RCT_SIZE_Y(&but->rect) + (data->dragstarty - my); + scopes->track_preview_height = BLI_rctf_size_y(&but->rect) + (data->dragstarty - my); } else { if (!scopes->track_locked) { @@ -4270,8 +4361,8 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr); scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED); - scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / BLI_RCT_SIZE_X(&but->block->rect); - scopes->marker->pos[1] += -dy * scopes->slide_scale[1] / BLI_RCT_SIZE_Y(&but->block->rect); + scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / BLI_rctf_size_x(&but->block->rect); + scopes->marker->pos[1] += -dy * scopes->slide_scale[1] / BLI_rctf_size_y(&but->block->rect); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); } @@ -4460,6 +4551,7 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) static int ui_but_menu(bContext *C, uiBut *but) { + ARegion *ar = CTX_wm_region(C); uiPopupMenu *pup; uiLayout *layout; int length; @@ -4471,17 +4563,8 @@ static int ui_but_menu(bContext *C, uiBut *but) button_timers_tooltip_remove(C, but); -#if 0 - if (but->rnaprop) - name = RNA_property_ui_name(but->rnaprop); - else if (but->optype && but->optype->srna) - name = RNA_struct_ui_name(but->optype->srna); - else - name = IFACE_("<needs_name>"); // XXX - should never happen. -#else uiButGetStrInfo(C, but, 1, &label); name = label.strinfo; -#endif pup = uiPupMenuBegin(C, name, ICON_NONE); layout = uiPupMenuLayout(pup); @@ -4525,7 +4608,9 @@ static int ui_but_menu(bContext *C, uiBut *but) } - else if (but->flag & UI_BUT_DRIVEN) ; + else if (but->flag & UI_BUT_DRIVEN) { + /* pass */ + } else if (is_anim) { if (length) { uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"), @@ -4533,9 +4618,10 @@ static int ui_but_menu(bContext *C, uiBut *but) uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"), ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0); } - else + else { uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"), ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0); + } } if (but->flag & UI_BUT_ANIMATED) { @@ -4561,17 +4647,21 @@ static int ui_but_menu(bContext *C, uiBut *but) uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"), ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0); } - else + else { uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"), ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0); + } uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"), ICON_NONE, "ANIM_OT_copy_driver_button"); - if (ANIM_driver_can_paste()) + if (ANIM_driver_can_paste()) { uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"), ICON_NONE, "ANIM_OT_paste_driver_button"); + } + } + else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) { + /* pass */ } - else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) ; else if (is_anim) { uiItemS(layout); @@ -4581,13 +4671,15 @@ static int ui_but_menu(bContext *C, uiBut *but) uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single Driver"), ICON_NONE, "ANIM_OT_driver_button_add", "all", 0); } - else + else { uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"), ICON_NONE, "ANIM_OT_driver_button_add", "all", 0); + } - if (ANIM_driver_can_paste()) + if (ANIM_driver_can_paste()) { uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"), ICON_NONE, "ANIM_OT_paste_driver_button"); + } } /* Keying Sets */ @@ -4624,9 +4716,10 @@ static int ui_but_menu(bContext *C, uiBut *but) uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"), ICON_NONE, "UI_OT_reset_default_button", "all", 0); } - else + else { uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"), ICON_NONE, "UI_OT_reset_default_button"); + } uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"), ICON_NONE, "UI_OT_copy_data_path_button"); @@ -4673,7 +4766,12 @@ static int ui_but_menu(bContext *C, uiBut *but) uiItemS(layout); } - + /* Show header tools for header buttons. */ + if (ar->regiontype == RGN_TYPE_HEADER) { + uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL); + uiItemS(layout); + } + { /* Docs */ char buf[512]; PointerRNA ptr_props; @@ -5231,12 +5329,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s /* automatic open pulldown block timer */ if (ELEM3(but->type, BLOCK, PULLDOWN, ICONTEXTROW)) { - if ((data->used_mouse == TRUE) && - (data->autoopentimer == FALSE) && - /* don't popup the first time, - * see description on this member for info */ - (but->block->auto_is_first_event == FALSE)) - { + if (data->used_mouse && !data->autoopentimer) { int time; if (but->block->auto_open == TRUE) { /* test for toolbox */ @@ -5256,8 +5349,6 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s data->autoopentimer = WM_event_add_timer(data->wm, data->window, TIMER, 0.02 * (double)time); } } - - but->block->auto_is_first_event = FALSE; } } else { @@ -5281,8 +5372,24 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s } else if (data->state == BUTTON_STATE_NUM_EDITING) { ui_numedit_end(but, data); - if (ui_is_a_warp_but(but)) - WM_cursor_grab_disable(CTX_wm_window(C)); + if (ui_is_a_warp_but(but)) { + +#ifdef USE_CONT_MOUSE_CORRECT + if (data->ungrab_mval[0] != FLT_MAX) { + int mouse_ungrab_xy[2]; + ui_block_to_window_fl(data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]); + mouse_ungrab_xy[0] = data->ungrab_mval[0]; + mouse_ungrab_xy[1] = data->ungrab_mval[1]; + + WM_cursor_grab_disable(data->window, mouse_ungrab_xy); + } + else { + WM_cursor_grab_disable(data->window, NULL); + } +#else + WM_cursor_grab_disable(data->window, ); +#endif + } } /* menu open */ if (state == BUTTON_STATE_MENU_OPEN) @@ -5345,6 +5452,10 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA data->window = CTX_wm_window(C); data->region = ar; +#ifdef USE_CONT_MOUSE_CORRECT + copy_v2_fl(data->ungrab_mval, FLT_MAX); +#endif + if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) { /* XXX curve is temp */ } @@ -5626,20 +5737,24 @@ void uiContextAnimUpdate(const bContext *C) ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f); ED_region_tag_redraw(ar); - if (but->active) + if (but->active) { activebut = but; - else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) + } + else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) { activebut = but; + } } } if (activebut) { /* always recurse into opened menu, so all buttons update (like colorpicker) */ uiHandleButtonData *data = activebut->active; - if (data && data->menu) + if (data && data->menu) { ar = data->menu->region; - else + } + else { return; + } } else { /* no active button */ @@ -5669,8 +5784,9 @@ static int ui_handle_button_over(bContext *C, wmEvent *event, ARegion *ar) if (event->type == MOUSEMOVE) { but = ui_but_find_mouse_over(ar, event->x, event->y); - if (but) + if (but) { button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); + } } else if (event->type == EVT_BUT_OPEN) { but = uit_but_find_open_event(ar, event); @@ -6173,7 +6289,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my) return 0; } -static 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 level) { ARegion *ar; uiBlock *block; @@ -6218,10 +6334,22 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle } /* first block own event func */ - if (block->block_event_func && block->block_event_func(C, block, event)) ; - /* events not for active search menu button */ + if (block->block_event_func && block->block_event_func(C, block, event)) { + /* pass */ + } /* events not for active search menu button */ else if (but == NULL || but->type != SEARCH_MENU) { switch (event->type) { + + + /* let the parent menu get the event */ +#define PASS_EVENT_TO_PARENT_IF_NONACTIVE \ + if ((level != 0) && (but == NULL)) { \ + menu->menuretval = UI_RETURN_OUT | UI_RETURN_OUT_PARENT; \ + BLI_assert(retval == WM_UI_HANDLER_CONTINUE); \ + break; \ + } (void)0 + + /* closing sublevels of pulldowns */ case LEFTARROWKEY: if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) @@ -6234,6 +6362,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle /* opening sublevels of pulldowns */ case RIGHTARROWKEY: if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) { + + PASS_EVENT_TO_PARENT_IF_NONACTIVE; + but = ui_but_find_activated(ar); if (!but) { @@ -6259,6 +6390,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle } else if (inside || (block->flag & UI_BLOCK_LOOP)) { if (event->val == KM_PRESS) { + + PASS_EVENT_TO_PARENT_IF_NONACTIVE; + but = ui_but_find_activated(ar); if (but) { /* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */ @@ -6338,6 +6472,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle if (act == 0) act = 10; if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) { + + PASS_EVENT_TO_PARENT_IF_NONACTIVE; + if (event->alt) act += 10; count = 0; @@ -6415,6 +6552,8 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle (event->ctrl == FALSE) && (event->oskey == FALSE)) { + PASS_EVENT_TO_PARENT_IF_NONACTIVE; + for (but = block->buttons.first; but; but = but->next) { if (but->menu_key == event->type) { @@ -6504,6 +6643,10 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle retval = WM_UI_HANDLER_BREAK; } } + + /* end switch */ +#undef PASS_EVENT_TO_PARENT_IF_NONACTIVE + } } @@ -6592,7 +6735,7 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo return WM_UI_HANDLER_BREAK; } -static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHandle *menu) +static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int level) { uiBut *but; uiHandleButtonData *data; @@ -6605,14 +6748,20 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa submenu = (data) ? data->menu : NULL; if (submenu) - retval = ui_handle_menus_recursive(C, event, submenu); + retval = ui_handle_menus_recursive(C, event, submenu, level + 1); /* now handle events for our own menu */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { - if (submenu && submenu->menuretval) + if (submenu && submenu->menuretval) { retval = ui_handle_menu_return_submenu(C, event, menu); - else - retval = ui_handle_menu_event(C, event, menu, (submenu == NULL)); + /* we may wan't to quit the submenu and handle the even in this menu */ + if ((retval == WM_UI_HANDLER_BREAK) && (submenu->menuretval & UI_RETURN_OUT_PARENT)) { + retval = ui_handle_menu_event(C, event, menu, level); + } + } + else { + retval = ui_handle_menu_event(C, event, menu, level); /* same as above */ + } } return retval; @@ -6700,7 +6849,7 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user if (data->state == BUTTON_STATE_MENU_OPEN) { /* handle events for menus and their buttons recursively, * this will handle events from the top to the bottom menu */ - retval = ui_handle_menus_recursive(C, event, data->menu); + retval = ui_handle_menus_recursive(C, event, data->menu, 0); /* handle events for the activated button */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { @@ -6744,7 +6893,7 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata) retval = WM_UI_HANDLER_CONTINUE; } - ui_handle_menus_recursive(C, event, menu); + ui_handle_menus_recursive(C, event, menu, 0); /* free if done, does not free handle itself */ if (menu->menuretval) { |