Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_query.c
| Show First 20 Lines • Show All 260 Lines • ▼ Show 20 Lines | else { | ||||
| const int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect); | const int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect); | ||||
| rect.xmin += delta / 2; | rect.xmin += delta / 2; | ||||
| rect.xmax -= delta / 2; | rect.xmax -= delta / 2; | ||||
| } | } | ||||
| return BLI_rcti_isect_pt(&rect, x, y); | return BLI_rcti_isect_pt(&rect, x, y); | ||||
| } | } | ||||
| static uiBut *ui_but_find(const ARegion *region, | |||||
| const uiButFindPollFn find_poll, | |||||
| const void *find_custom_data) | |||||
| { | |||||
| LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | |||||
| LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { | |||||
| if (find_poll && find_poll(but, find_custom_data) == false) { | |||||
| continue; | |||||
| } | |||||
| return but; | |||||
| } | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| /* x and y are only used in case event is NULL... */ | /* x and y are only used in case event is NULL... */ | ||||
| uiBut *ui_but_find_mouse_over_ex(const ARegion *region, | uiBut *ui_but_find_mouse_over_ex(const ARegion *region, | ||||
| const int x, | const int x, | ||||
| const int y, | const int y, | ||||
| const bool labeledit) | const bool labeledit, | ||||
| const uiButFindPollFn find_poll, | |||||
| const void *find_custom_data) | |||||
| { | { | ||||
| uiBut *butover = NULL; | uiBut *butover = NULL; | ||||
| if (!ui_region_contains_point_px(region, x, y)) { | if (!ui_region_contains_point_px(region, x, y)) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| float mx = x, my = y; | float mx = x, my = y; | ||||
| ui_window_to_block_fl(region, block, &mx, &my); | ui_window_to_block_fl(region, block, &mx, &my); | ||||
| LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { | LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { | ||||
| if (find_poll && find_poll(but, find_custom_data) == false) { | |||||
| continue; | |||||
| } | |||||
| if (ui_but_is_interactive(but, labeledit)) { | if (ui_but_is_interactive(but, labeledit)) { | ||||
| if (but->pie_dir != UI_RADIAL_NONE) { | if (but->pie_dir != UI_RADIAL_NONE) { | ||||
| if (ui_but_isect_pie_seg(block, but)) { | if (ui_but_isect_pie_seg(block, but)) { | ||||
| butover = but; | butover = but; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else if (ui_but_contains_pt(but, mx, my)) { | else if (ui_but_contains_pt(but, mx, my)) { | ||||
| Show All 12 Lines | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| } | } | ||||
| } | } | ||||
| return butover; | return butover; | ||||
| } | } | ||||
| uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event) | uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event) | ||||
| { | { | ||||
| return ui_but_find_mouse_over_ex(region, event->x, event->y, event->ctrl != 0); | return ui_but_find_mouse_over_ex(region, event->x, event->y, event->ctrl != 0, NULL, NULL); | ||||
| } | } | ||||
| uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px) | uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px) | ||||
| { | { | ||||
| if (!ui_region_contains_rect_px(region, rect_px)) { | if (!ui_region_contains_rect_px(region, rect_px)) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| Show All 24 Lines | if (block->flag & UI_BLOCK_CLIP_EVENTS) { | ||||
| if (BLI_rctf_isect(&block->rect, &rect_block, NULL)) { | if (BLI_rctf_isect(&block->rect, &rect_block, NULL)) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return butover; | return butover; | ||||
| } | } | ||||
| uiBut *ui_list_find_mouse_over_ex(ARegion *region, int x, int y) | uiBut *ui_list_find_mouse_over_ex(const ARegion *region, int x, int y) | ||||
| { | { | ||||
| if (!ui_region_contains_point_px(region, x, y)) { | if (!ui_region_contains_point_px(region, x, y)) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| float mx = x, my = y; | float mx = x, my = y; | ||||
| ui_window_to_block_fl(region, block, &mx, &my); | ui_window_to_block_fl(region, block, &mx, &my); | ||||
| LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { | LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { | ||||
| if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) { | if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) { | ||||
| return but; | return but; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| uiBut *ui_list_find_mouse_over(ARegion *region, const wmEvent *event) | uiBut *ui_list_find_mouse_over(const ARegion *region, const wmEvent *event) | ||||
| { | { | ||||
| if (event == NULL) { | |||||
| /* If there is no info about the mouse, just act as if there is nothing underneath it. */ | |||||
| return NULL; | |||||
| } | |||||
| return ui_list_find_mouse_over_ex(region, event->x, event->y); | return ui_list_find_mouse_over_ex(region, event->x, event->y); | ||||
| } | } | ||||
| uiList *UI_list_find_mouse_over(const ARegion *region, const wmEvent *event) | |||||
| { | |||||
| uiBut *list_but = ui_list_find_mouse_over(region, event); | |||||
| if (!list_but) { | |||||
| return NULL; | |||||
| } | |||||
| return list_but->custom_data; | |||||
| } | |||||
| static bool ui_list_contains_row(const uiBut *listbox_but, const uiBut *listrow_but) | |||||
| { | |||||
| BLI_assert(listbox_but->type == UI_BTYPE_LISTBOX); | |||||
| BLI_assert(listrow_but->type == UI_BTYPE_LISTROW); | |||||
| /* The list box and its rows have the same RNA data (active data pointer/prop). */ | |||||
| return ui_but_rna_equals(listbox_but, listrow_but); | |||||
| } | |||||
| static bool ui_but_is_listbox_with_row(const uiBut *but, const void *customdata) | |||||
| { | |||||
| const uiBut *row_but = customdata; | |||||
| return (but->type == UI_BTYPE_LISTBOX) && ui_list_contains_row(but, row_but); | |||||
| } | |||||
| uiBut *ui_list_find_from_row(const ARegion *region, const uiBut *row_but) | |||||
| { | |||||
| return ui_but_find(region, ui_but_is_listbox_with_row, row_but); | |||||
| } | |||||
| static bool ui_but_is_listrow(const uiBut *but, const void *UNUSED(customdata)) | |||||
| { | |||||
| return but->type == UI_BTYPE_LISTROW; | |||||
| } | |||||
| uiBut *ui_list_row_find_mouse_over(const ARegion *region, const int x, const int y) | |||||
| { | |||||
| return ui_but_find_mouse_over_ex(region, x, y, false, ui_but_is_listrow, NULL); | |||||
| } | |||||
| struct ListRowFindIndexData { | |||||
| int index; | |||||
| uiBut *listbox; | |||||
| }; | |||||
| static bool ui_but_is_listrow_at_index(const uiBut *but, const void *customdata) | |||||
| { | |||||
| const struct ListRowFindIndexData *find_data = customdata; | |||||
| return ui_but_is_listrow(but, NULL) && ui_list_contains_row(find_data->listbox, but) && | |||||
| (but->hardmax == find_data->index); | |||||
| } | |||||
| uiBut *ui_list_row_find_from_index(const ARegion *region, const int index, uiBut *listbox) | |||||
| { | |||||
| BLI_assert(listbox->type == UI_BTYPE_LISTBOX); | |||||
| struct ListRowFindIndexData data = { | |||||
| .index = index, | |||||
| .listbox = listbox, | |||||
| }; | |||||
| return ui_but_find(region, ui_but_is_listrow_at_index, &data); | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Button (#uiBut) Relations | /** \name Button (#uiBut) Relations | ||||
| * \{ */ | * \{ */ | ||||
| uiBut *ui_but_prev(uiBut *but) | uiBut *ui_but_prev(uiBut *but) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Block (#uiBlock) State | /** \name Block (#uiBlock) State | ||||
| * \{ */ | * \{ */ | ||||
| uiBut *ui_block_active_but_get(const uiBlock *block) | |||||
| { | |||||
| LISTBASE_FOREACH (uiBut *, but, &block->buttons) { | |||||
| if (but->active) { | |||||
| return but; | |||||
| } | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| bool ui_block_is_menu(const uiBlock *block) | bool ui_block_is_menu(const uiBlock *block) | ||||
| { | { | ||||
| return (((block->flag & UI_BLOCK_LOOP) != 0) && | return (((block->flag & UI_BLOCK_LOOP) != 0) && | ||||
| /* non-menu popups use keep-open, so check this is off */ | /* non-menu popups use keep-open, so check this is off */ | ||||
| ((block->flag & UI_BLOCK_KEEP_OPEN) == 0)); | ((block->flag & UI_BLOCK_KEEP_OPEN) == 0)); | ||||
| } | } | ||||
| bool ui_block_is_popover(const uiBlock *block) | bool ui_block_is_popover(const uiBlock *block) | ||||
| ▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Region (#ARegion) State | /** \name Region (#ARegion) State | ||||
| * \{ */ | * \{ */ | ||||
| uiBut *ui_region_find_active_but(ARegion *region) | uiBut *ui_region_find_active_but(ARegion *region) | ||||
| { | { | ||||
| LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| LISTBASE_FOREACH (uiBut *, but, &block->buttons) { | uiBut *but = ui_block_active_but_get(block); | ||||
| if (but->active) { | if (but) { | ||||
| return but; | return but; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| uiBut *ui_region_find_first_but_test_flag(ARegion *region, int flag_include, int flag_exclude) | uiBut *ui_region_find_first_but_test_flag(ARegion *region, int flag_include, int flag_exclude) | ||||
| { | { | ||||
| LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| LISTBASE_FOREACH (uiBut *, but, &block->buttons) { | LISTBASE_FOREACH (uiBut *, but, &block->buttons) { | ||||
| ▲ Show 20 Lines • Show All 102 Lines • Show Last 20 Lines | |||||