diff options
Diffstat (limited to 'source/blender/editors/interface/interface_handlers.c')
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 524 |
1 files changed, 213 insertions, 311 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 06b6099cec7..ac7ed3d5106 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -38,11 +38,7 @@ #include "MEM_guardedalloc.h" #include "DNA_brush_types.h" -#include "DNA_sensor_types.h" -#include "DNA_controller_types.h" -#include "DNA_actuator_types.h" -#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -72,6 +68,7 @@ #include "ED_undo.h" #include "UI_interface.h" +#include "UI_view2d.h" #include "BLF_api.h" @@ -109,8 +106,6 @@ #define UI_MAX_PASSWORD_STR 128 /* proto */ -static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to); -static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to); static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event); static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b); static void ui_textedit_string_set(uiBut *but, struct uiHandleButtonData *data, const char *str); @@ -125,7 +120,7 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve #define BUTTON_FLASH_DELAY 0.020 #define MENU_SCROLL_INTERVAL 0.1 #define PIE_MENU_INTERVAL 0.01 -#define BUTTON_AUTO_OPEN_THRESH 0.3 +#define BUTTON_AUTO_OPEN_THRESH 0.2 #define BUTTON_MOUSE_TOWARDS_THRESH 1.0 /* pixels to move the cursor to get out of keyboard navigation */ #define BUTTON_KEYNAV_PX_LIMIT 8 @@ -276,6 +271,7 @@ typedef struct uiHandleButtonData { /* booleans (could be made into flags) */ bool cancel, escapecancel; bool applied, applied_interactive; + bool changed_cursor; wmTimer *flashtimer; /* edited value */ @@ -619,11 +615,8 @@ PointerRNA *ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext, static void popup_check(bContext *C, wmOperator *op) { - if (op && op->type->check && op->type->check(C, op)) { - /* check for popup and re-layout buttons */ - ARegion *ar_menu = CTX_wm_menu(C); - if (ar_menu) - ED_region_tag_refresh_ui(ar_menu); + if (op && op->type->check) { + op->type->check(C, op); } } @@ -704,8 +697,7 @@ static void ui_apply_but_undo(uiBut *but) const char *str = NULL; /* define which string to use for undo */ - if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) str = "Add button link"; - else if (but->type == UI_BTYPE_MENU) str = but->drawstr; + if (but->type == UI_BTYPE_MENU) str = but->drawstr; else if (but->drawstr[0]) str = but->drawstr; else str = but->tip; @@ -917,6 +909,20 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) data->applied = true; } +static void ui_apply_but_TAB(bContext *C, uiBut *but, uiHandleButtonData *data) +{ + if (data->str) { + ui_but_string_set(C, but, data->str); + ui_but_update_edited(but); + } + else { + ui_apply_but_func(C, but); + } + + data->retval = but->retval; + data->applied = true; +} + static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) { if (data->str) { @@ -1219,6 +1225,9 @@ static bool ui_drag_toggle_but_is_supported(const uiBut *but) if (ui_but_is_bool(but)) { return true; } + else if (UI_but_is_decorator(but)) { + return ELEM(but->icon, ICON_SPACE2, ICON_SPACE3, ICON_DOT, ICON_LIBRARY_DATA_OVERRIDE); + } else { return false; } @@ -1229,6 +1238,9 @@ static bool ui_drag_toggle_but_is_pushed(uiBut *but) if (ui_but_is_bool(but)) { return ui_but_is_pushed(but); } + else if (UI_but_is_decorator(but)) { + return (but->icon == ICON_SPACE2); + } else { return false; } @@ -1239,7 +1251,6 @@ typedef struct uiDragToggleHandle { bool is_init; bool is_set; float but_cent_start[2]; - eButType but_type_start; bool xy_lock[2]; int xy_init[2]; @@ -1247,7 +1258,7 @@ typedef struct uiDragToggleHandle { } uiDragToggleHandle; static bool ui_drag_toggle_set_xy_xy( - bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start, + bContext *C, ARegion *ar, const bool is_set, const int xy_src[2], const int xy_dst[2]) { /* popups such as layers won't re-evaluate on redraw */ @@ -1271,7 +1282,7 @@ static bool ui_drag_toggle_set_xy_xy( if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) { /* execute the button */ - if (ui_drag_toggle_but_is_supported(but) && but->type == but_type_start) { + if (ui_drag_toggle_but_is_supported(but)) { /* is it pressed? */ bool is_set_but = ui_drag_toggle_but_is_pushed(but); if (is_set_but != is_set) { @@ -1345,7 +1356,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const /* touch all buttons between last mouse coord and this one */ - do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->is_set, drag_info->but_type_start, drag_info->xy_last, xy); + do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->is_set, drag_info->xy_last, xy); if (do_draw) { ED_region_tag_redraw(ar); @@ -1725,7 +1736,6 @@ static bool ui_but_drag_init( drag_info->is_set = ui_drag_toggle_but_is_pushed(but); drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect); drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect); - drag_info->but_type_start = but->type; copy_v2_v2_int(drag_info->xy_init, &event->x); copy_v2_v2_int(drag_info->xy_last, &event->x); @@ -1792,223 +1802,6 @@ static bool ui_but_drag_init( /* ********************** linklines *********************** */ -static void ui_linkline_remove_active(uiBlock *block) -{ - uiBut *but; - uiLink *link; - uiLinkLine *line, *nline; - int a, b; - - for (but = block->buttons.first; but; but = but->next) { - if (but->type == UI_BTYPE_LINK && but->link) { - for (line = but->link->lines.first; line; line = nline) { - nline = line->next; - - if (line->flag & UI_SELECT) { - BLI_remlink(&but->link->lines, line); - - link = line->from->link; - - /* are there more pointers allowed? */ - if (link->ppoin) { - - if (*(link->totlink) == 1) { - *(link->totlink) = 0; - MEM_freeN(*(link->ppoin)); - *(link->ppoin) = NULL; - } - else { - b = 0; - for (a = 0; a < (*(link->totlink)); a++) { - - if ((*(link->ppoin))[a] != line->to->poin) { - (*(link->ppoin))[b] = (*(link->ppoin))[a]; - b++; - } - } - (*(link->totlink))--; - } - } - else { - *(link->poin) = NULL; - } - - MEM_freeN(line); - } - } - } - } -} - - -static uiLinkLine *ui_but_find_link(uiBut *from, uiBut *to) -{ - uiLinkLine *line; - uiLink *link; - - link = from->link; - if (link) { - for (line = link->lines.first; line; line = line->next) { - if (line->from == from && line->to == to) { - return line; - } - } - } - return NULL; -} - -/* XXX BAD BAD HACK, fixme later **************** */ -/* Try to add an AND Controller between the sensor and the actuator logic bricks and to connect them all */ -static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to) -{ - Object *ob = NULL; - bSensor *sens_iter; - bActuator *act_to, *act_iter; - bController *cont; - bController ***sens_from_links; - uiBut *tmp_but; - - uiLink *link = from->link; - - PointerRNA props_ptr, object_ptr; - - if (link->ppoin) - sens_from_links = (bController ***)(link->ppoin); - else return; - - act_to = (bActuator *)(to->poin); - - /* (1) get the object */ - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) - { - for (sens_iter = ob_iter->sensors.first; sens_iter; sens_iter = sens_iter->next) { - if (&(sens_iter->links) == sens_from_links) { - ob = ob_iter; - break; - } - } - if (ob) break; - } CTX_DATA_END; - - if (!ob) return; - - /* (2) check if the sensor and the actuator are from the same object */ - for (act_iter = ob->actuators.first; act_iter; act_iter = (bActuator *)act_iter->next) { - if (act_iter == act_to) - break; - } - - /* 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, &props_ptr) & OPERATOR_FINISHED) { - cont = (bController *)ob->controllers.last; - /* 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... */ - cont->type = CONT_LOGIC_AND; - - /* (4) link the sensor->controller->actuator */ - tmp_but = MEM_callocN(sizeof(uiBut), "uiBut"); - UI_but_link_set( - tmp_but, (void **)&cont, (void ***)&(cont->links), - &cont->totlinks, from->link->tocode, (int)to->hardmin); - tmp_but->hardmin = from->link->tocode; - tmp_but->poin = (char *)cont; - - tmp_but->type = UI_BTYPE_INLINK; - ui_but_link_add(C, from, tmp_but); - - tmp_but->type = UI_BTYPE_LINK; - ui_but_link_add(C, tmp_but, to); - - /* (5) garbage collection */ - MEM_freeN(tmp_but->link); - MEM_freeN(tmp_but); - } - WM_operator_properties_free(&props_ptr); -} - -static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to) -{ - /* in 'from' we have to add a link to 'to' */ - uiLink *link; - uiLinkLine *line; - void **oldppoin; - int a; - - if ((line = ui_but_find_link(from, to))) { - line->flag |= UI_SELECT; - ui_linkline_remove_active(from->block); - return; - } - - if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_INLINK) { - return; - } - else if (from->type == UI_BTYPE_LINK && to->type == UI_BTYPE_INLINK) { - if (from->link->tocode != (int)to->hardmin) { - ui_but_smart_controller_add(C, from, to); - return; - } - } - else if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_LINK) { - if (to->link->tocode == (int)from->hardmin) { - return; - } - } - - link = from->link; - - /* are there more pointers allowed? */ - if (link->ppoin) { - oldppoin = *(link->ppoin); - - (*(link->totlink))++; - *(link->ppoin) = MEM_callocN(*(link->totlink) * sizeof(void *), "new link"); - - for (a = 0; a < (*(link->totlink)) - 1; a++) { - (*(link->ppoin))[a] = oldppoin[a]; - } - (*(link->ppoin))[a] = to->poin; - - if (oldppoin) MEM_freeN(oldppoin); - } - else { - *(link->poin) = to->poin; - } - -} - - -static void ui_apply_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data) -{ - ARegion *ar = CTX_wm_region(C); - uiBut *bt; - - for (bt = but->block->buttons.first; bt; bt = bt->next) { - if (ui_but_contains_point_px(ar, bt, but->linkto[0] + ar->winrct.xmin, but->linkto[1] + ar->winrct.ymin) ) - break; - } - if (bt && bt != but) { - if (!ELEM(bt->type, UI_BTYPE_LINK, UI_BTYPE_INLINK) || !ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) - return; - - if (but->type == UI_BTYPE_LINK) ui_but_link_add(C, but, bt); - else ui_but_link_add(C, bt, but); - - ui_apply_but_func(C, but); - data->retval = but->retval; - } - data->applied = true; -} - static void ui_apply_but_IMAGE(bContext *C, uiBut *but, uiHandleButtonData *data) { ui_apply_but_func(C, but); @@ -2127,6 +1920,9 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton case UI_BTYPE_LISTROW: ui_apply_but_ROW(C, block, but, data); break; + case UI_BTYPE_TAB: + ui_apply_but_TAB(C, but, data); + break; case UI_BTYPE_SCROLL: case UI_BTYPE_GRIP: case UI_BTYPE_NUM: @@ -2162,10 +1958,6 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton case UI_BTYPE_HOTKEY_EVENT: ui_apply_but_BUT(C, but, data); break; - case UI_BTYPE_LINK: - case UI_BTYPE_INLINK: - ui_apply_but_LINK(C, but, data); - break; case UI_BTYPE_IMAGE: ui_apply_but_IMAGE(C, but, data); break; @@ -3179,6 +2971,9 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) ui_searchbox_free(C, data->searchbox); data->searchbox = NULL; + if (but->free_search_arg) { + MEM_SAFE_FREE(but->search_arg); + } } but->editstr = NULL; @@ -3658,6 +3453,7 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat uiBlockCreateFunc func = NULL; uiBlockHandleCreateFunc handlefunc = NULL; uiMenuCreateFunc menufunc = NULL; + uiMenuCreateFunc popoverfunc = NULL; void *arg = NULL; switch (but->type) { @@ -3677,6 +3473,11 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat menufunc = but->menu_create_func; arg = but->poin; break; + case UI_BTYPE_POPOVER: + BLI_assert(but->menu_create_func); + popoverfunc = but->menu_create_func; + arg = but->poin; + break; case UI_BTYPE_COLOR: ui_but_v3_get(but, data->origvec); copy_v3_v3(data->vec, data->origvec); @@ -3701,6 +3502,11 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat if (but->block->handle) data->menu->popup = but->block->handle->popup; } + else if (popoverfunc) { + data->menu = ui_popover_panel_create(C, data->region, but, popoverfunc, arg); + if (but->block->handle) + data->menu->popup = but->block->handle->popup; + } #ifdef USE_ALLSELECT { @@ -3947,6 +3753,43 @@ static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, c return BLI_rcti_isect_pt(&icon_rect, x, y); } +static int ui_do_but_TAB(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) +{ + if (data->state == BUTTON_STATE_HIGHLIGHT) { + if ((event->type == LEFTMOUSE) && + ((event->val == KM_DBL_CLICK) || event->ctrl)) + { + button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); + return WM_UI_HANDLER_BREAK; + } + else if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && (event->val == KM_CLICK)) { + const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR; + + if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) { + uiButTab *tab = (uiButTab *)but; + wmOperatorType *ot_backup = but->optype; + + but->optype = tab->unlink_ot; + /* Force calling unlink/delete operator. */ + ui_apply_but(C, block, but, data, true); + but->optype = ot_backup; + } + button_activate_state(C, but, BUTTON_STATE_EXIT); + return WM_UI_HANDLER_BREAK; + } + } + else if (data->state == BUTTON_STATE_TEXT_EDITING) { + ui_do_but_textedit(C, block, but, data, event); + return WM_UI_HANDLER_BREAK; + } + else if (data->state == BUTTON_STATE_TEXT_SELECTING) { + ui_do_but_textedit_select(C, block, but, data, event); + return WM_UI_HANDLER_BREAK; + } + + return WM_UI_HANDLER_CONTINUE; +} + static int ui_do_but_TEX( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) @@ -4375,6 +4218,54 @@ static bool ui_numedit_but_NUM( return changed; } +static void ui_numedit_set_active(uiBut *but) +{ + int oldflag = but->drawflag; + but->drawflag &= ~(UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT); + + uiHandleButtonData *data = but->active; + if (!data) { + return; + } + + /* Ignore once we start dragging. */ + if (data->dragchange == false) { + const float handle_width = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect) * 0.7f); + /* we can click on the side arrows to increment/decrement, + * or click inside to edit the value directly */ + int mx = data->window->eventstate->x; + int my = data->window->eventstate->x; + ui_window_to_block(data->region, but->block, &mx, &my); + + if (mx < (but->rect.xmin + handle_width)) { + but->drawflag |= UI_BUT_ACTIVE_LEFT; + } + else if (mx > (but->rect.xmax - handle_width)) { + but->drawflag |= UI_BUT_ACTIVE_RIGHT; + } + } + + /* Don't change the cursor once pressed. */ + if ((but->flag & UI_SELECT) == 0) { + if ((but->drawflag & (UI_BUT_ACTIVE_LEFT)) || (but->drawflag & (UI_BUT_ACTIVE_RIGHT))) { + if (data->changed_cursor) { + WM_cursor_modal_restore(data->window); + data->changed_cursor = false; + } + } + else { + if (data->changed_cursor == false) { + WM_cursor_modal_set(data->window, CURSOR_X_MOVE); + data->changed_cursor = true; + } + } + } + + if (but->drawflag != oldflag) { + ED_region_tag_redraw(data->region); + } +} + static int ui_do_but_NUM( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) @@ -4388,6 +4279,7 @@ static int ui_do_but_NUM( my = screen_my = event->y; ui_window_to_block(data->region, block, &mx, &my); + ui_numedit_set_active(but); if (data->state == BUTTON_STATE_HIGHLIGHT) { int type = event->type, val = event->val; @@ -4401,10 +4293,14 @@ static int ui_do_but_NUM( retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */ else if (type == WHEELDOWNMOUSE && event->ctrl) { mx = but->rect.xmin; + but->drawflag &= ~UI_BUT_ACTIVE_RIGHT; + but->drawflag |= UI_BUT_ACTIVE_LEFT; click = 1; } else if (type == WHEELUPMOUSE && event->ctrl) { mx = but->rect.xmax; + but->drawflag &= ~UI_BUT_ACTIVE_LEFT; + but->drawflag |= UI_BUT_ACTIVE_RIGHT; click = 1; } else if (event->val == KM_PRESS) { @@ -4497,16 +4393,13 @@ static int ui_do_but_NUM( /* we can click on the side arrows to increment/decrement, * or click inside to edit the value directly */ float tempf, softmin, softmax; - float handlewidth; int temp; softmin = but->softmin; softmax = but->softmax; - handlewidth = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect)); - if (!ui_but_is_float(but)) { - if (mx < (but->rect.xmin + handlewidth)) { + if (but->drawflag & UI_BUT_ACTIVE_LEFT) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); temp = (int)data->value - 1; @@ -4517,7 +4410,7 @@ static int ui_do_but_NUM( button_activate_state(C, but, BUTTON_STATE_EXIT); } - else if (mx > (but->rect.xmax - handlewidth)) { + else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); temp = (int)data->value + 1; @@ -4533,7 +4426,7 @@ static int ui_do_but_NUM( } } else { - if (mx < (but->rect.xmin + handlewidth)) { + if (but->drawflag & UI_BUT_ACTIVE_LEFT) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); tempf = (float)data->value - (UI_PRECISION_FLOAT_SCALE * but->a1); @@ -4542,7 +4435,7 @@ static int ui_do_but_NUM( button_activate_state(C, but, BUTTON_STATE_EXIT); } - else if (mx > but->rect.xmax - handlewidth) { + else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); tempf = (float)data->value + (UI_PRECISION_FLOAT_SCALE * but->a1); @@ -5265,7 +5158,8 @@ static int ui_do_but_COLOR( if (!event->ctrl) { float color[3]; Scene *scene = CTX_data_scene(C); - Paint *paint = BKE_paint_get_active(scene); + ViewLayer *view_layer = CTX_data_view_layer(C); + Paint *paint = BKE_paint_get_active(scene, view_layer); Brush *brush = BKE_paint_brush(paint); if (brush->flag & BRUSH_USE_GRADIENT) { @@ -6182,6 +6076,7 @@ static int ui_do_but_CURVE( int mx, my, a; bool changed = false; Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); mx = event->x; my = event->y; @@ -6310,7 +6205,7 @@ static int ui_do_but_CURVE( } else { curvemapping_changed(cumap, true); /* remove doubles */ - BKE_paint_invalidate_cursor_overlay(scene, cumap); + BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap); } } @@ -6476,35 +6371,6 @@ static int ui_do_but_WAVEFORM( return WM_UI_HANDLER_CONTINUE; } -static int ui_do_but_LINK( - bContext *C, uiBut *but, - uiHandleButtonData *data, const wmEvent *event) -{ - VECCOPY2D(but->linkto, event->mval); - - if (data->state == BUTTON_STATE_HIGHLIGHT) { - if (event->type == LEFTMOUSE && event->val == KM_PRESS) { - button_activate_state(C, but, BUTTON_STATE_WAIT_RELEASE); - return WM_UI_HANDLER_BREAK; - } - else if (event->type == LEFTMOUSE && but->block->handle) { - button_activate_state(C, but, BUTTON_STATE_EXIT); - return WM_UI_HANDLER_BREAK; - } - } - else if (data->state == BUTTON_STATE_WAIT_RELEASE) { - - if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { - if (!(but->flag & UI_SELECT)) - data->cancel = true; - button_activate_state(C, but, BUTTON_STATE_EXIT); - return WM_UI_HANDLER_BREAK; - } - } - - return WM_UI_HANDLER_CONTINUE; -} - static bool ui_numedit_but_TRACKPREVIEW( bContext *C, uiBut *but, uiHandleButtonData *data, int mx, int my, @@ -6648,6 +6514,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * case UI_BTYPE_HOTKEY_EVENT: retval = ui_do_but_HOTKEYEVT(C, but, data, event); break; + case UI_BTYPE_TAB: + retval = ui_do_but_TAB(C, block, but, data, event); + break; case UI_BTYPE_BUT_TOGGLE: case UI_BTYPE_TOGGLE: case UI_BTYPE_ICON_TOGGLE: @@ -6705,6 +6574,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * retval = ui_do_but_TEX(C, block, but, data, event); break; case UI_BTYPE_MENU: + case UI_BTYPE_POPOVER: case UI_BTYPE_BLOCK: case UI_BTYPE_PULLDOWN: retval = ui_do_but_BLOCK(C, but, data, event); @@ -6733,10 +6603,6 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * case UI_BTYPE_HSVCIRCLE: retval = ui_do_but_HSVCIRCLE(C, block, but, data, event); break; - case UI_BTYPE_LINK: - case UI_BTYPE_INLINK: - retval = ui_do_but_LINK(C, but, data, event); - break; case UI_BTYPE_TRACK_PREVIEW: retval = ui_do_but_TRACKPREVIEW(C, block, but, data, event); break; @@ -6744,6 +6610,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * /* quiet warnings for unhandled types */ case UI_BTYPE_SEPR: case UI_BTYPE_SEPR_LINE: + case UI_BTYPE_SEPR_SPACER: case UI_BTYPE_EXTRA: break; } @@ -6920,12 +6787,11 @@ bool ui_but_is_active(ARegion *ar) /* is called by notifier */ void UI_screen_free_active_but(const bContext *C, bScreen *screen) { - ScrArea *sa = screen->areabase.first; + wmWindow *win = CTX_wm_window(C); - for (; sa; sa = sa->next) { - ARegion *ar = sa->regionbase.first; - for (; ar; ar = ar->next) { - uiBut *but = ui_but_find_active_in_region(ar); + ED_screen_areas_iter(win, screen, area) { + for (ARegion *region = area->regionbase.first; region; region = region->next) { + uiBut *but = ui_but_find_active_in_region(region); if (but) { uiHandleButtonData *data = but->active; @@ -7011,7 +6877,7 @@ static bool ui_region_contains_point_px(ARegion *ar, int x, int y) ui_window_to_region(ar, &mx, &my); /* check if in the rect */ - if (!BLI_rcti_isect_pt(&v2d->mask, mx, my)) { + if (!BLI_rcti_isect_pt(&v2d->mask, mx, my) || UI_view2d_mouse_in_scrollers(ar, &ar->v2d, x, y)) { return false; } } @@ -7166,7 +7032,7 @@ void UI_but_tooltip_refresh(bContext *C, uiBut *but) { uiHandleButtonData *data = but->active; if (data) { - bScreen *sc = data->window->screen; + bScreen *sc = WM_window_get_active_screen(data->window); if (sc->tool_tip && sc->tool_tip->region) { WM_tooltip_refresh(C, data->window); } @@ -7232,7 +7098,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s button_tooltip_timer_reset(C, but); /* automatic open pulldown block timer */ - if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) { + if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { if (data->used_mouse && !data->autoopentimer) { int time; @@ -7442,6 +7308,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect)); WM_cursor_modal_set(data->window, horizontal ? CURSOR_X_MOVE : CURSOR_Y_MOVE); } + else if (but->type == UI_BTYPE_NUM) { + ui_numedit_set_active(but); + } } static void button_activate_exit( @@ -7535,8 +7404,13 @@ static void button_activate_exit( ui_selectcontext_end(but, &data->select_others); #endif - /* redraw (data is but->active!) */ + if (data->changed_cursor) { + WM_cursor_modal_restore(data->window); + } + + /* redraw and refresh (for popups) */ ED_region_tag_redraw(data->region); + ED_region_tag_refresh_ui(data->region); /* clean up button */ if (but->active) { @@ -7722,6 +7596,11 @@ void UI_context_update_anim_flag(const bContext *C) for (block = ar->uiblocks.first; block; block = block->next) { for (but = block->buttons.first; but; but = but->next) { ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f); + ui_but_override_flag(but); + if (UI_but_is_decorator(but)) { + ui_but_anim_decorate_update_from_flag(but); + } + ED_region_tag_redraw(ar); if (but->active) { @@ -7909,8 +7788,29 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) case EVT_BUT_CANCEL: data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); - retval = WM_UI_HANDLER_CONTINUE; break; +#ifdef USE_UI_POPOVER_ONCE + case LEFTMOUSE: + { + if (event->val == KM_RELEASE) { + if (block->flag & UI_BLOCK_POPOVER_ONCE) { + if (!(but->flag & UI_BUT_DISABLED)) { + if (ui_but_is_popover_once_compat(but)) { + data->cancel = false; + button_activate_state(C, but, BUTTON_STATE_EXIT); + retval = WM_UI_HANDLER_BREAK; + block->handle->menuretval = UI_RETURN_OK; + } + else if (ui_but_is_editable_as_text(but)) { + ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_TEXT_EDITING); + retval = WM_UI_HANDLER_BREAK; + } + } + } + } + break; + } +#endif case MOUSEMOVE: { uiBut *but_other = ui_but_find_mouse_over(ar, event); @@ -7949,7 +7849,6 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); } - retval = WM_UI_HANDLER_CONTINUE; break; } /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */ @@ -7960,10 +7859,11 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) UI_but_tooltip_timer_remove(C, but); ATTR_FALLTHROUGH; default: - /* handle button type specific events */ - retval = ui_do_button(C, block, but, event); break; } + + /* handle button type specific events */ + retval = ui_do_button(C, block, but, event); } else if (data->state == BUTTON_STATE_WAIT_RELEASE) { switch (event->type) { @@ -7992,12 +7892,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) break; } case MOUSEMOVE: - if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) { - but->flag |= UI_SELECT; - ui_do_button(C, block, but, event); - ED_region_tag_redraw(ar); - } - else { + { /* deselect the button when moving the mouse away */ /* also de-activate for buttons that only show higlights */ if (ui_but_contains_point_px(ar, but, event->x, event->y)) { @@ -8260,13 +8155,8 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar, } if (redraw) { - if (listbox->block->flag & UI_BLOCK_POPUP) { - /* popups need special refreshing */ - ED_region_tag_refresh_ui(ar); - } - else { - ED_region_tag_redraw(ar); - } + ED_region_tag_redraw(ar); + ED_region_tag_refresh_ui(ar); } return retval; @@ -8525,6 +8415,9 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt) dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD; } + /* remember scroll offset for refreshes */ + block->handle->scrolloffset += dy; + /* apply scroll offset */ for (bt = block->buttons.first; bt; bt = bt->next) { bt->rect.ymin += dy; @@ -8677,7 +8570,7 @@ static int ui_handle_menu_event( add_v2_v2v2_int(menu->popup_create_vars.event_xy, menu->popup_create_vars.event_xy, mdiff); - ui_popup_translate(C, ar, mdiff); + ui_popup_translate(ar, mdiff); } return retval; @@ -9061,6 +8954,15 @@ static int ui_handle_menu_event( retval = ui_handle_menu_button(C, event, menu); } +#ifdef USE_UI_POPOVER_ONCE + if (block->flag & UI_BLOCK_POPOVER_ONCE) { + if ((event->type == LEFTMOUSE) && (event->val == KM_RELEASE)) { + UI_popover_once_clear(menu->popup_create_vars.arg); + block->flag &= ~UI_BLOCK_POPOVER_ONCE; + } + } +#endif + /* Don't handle double click events, rehandle as regular press/release. */ if (retval == WM_UI_HANDLER_CONTINUE && event->val == KM_DBL_CLICK) { return retval; @@ -9680,10 +9582,10 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE if ((data->state == BUTTON_STATE_MENU_OPEN) && (is_inside_menu == false) && /* make sure mouse isn't inside another menu (see T43247) */ - (but->type == UI_BTYPE_PULLDOWN) && + (ELEM(but->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) && (but_other = ui_but_find_mouse_over(ar, event)) && (but != but_other) && - (but->type == but_other->type)) + (ELEM(but_other->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER))) { /* if mouse moves to a different root-level menu button, * open it to replace the current menu */ |