Blender V4.3
interface_query.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "BLI_listbase.h"
12#include "BLI_math_rotation.h"
13#include "BLI_math_vector.h"
14#include "BLI_rect.h"
15#include "BLI_string.h"
16#include "BLI_utildefines.h"
17
18#include "DNA_screen_types.h"
19
20#include "UI_interface.hh"
21#include "UI_view2d.hh"
22
23#include "RNA_access.hh"
24
25#include "interface_intern.hh"
26
27#include "UI_abstract_view.hh"
28
29#include "WM_api.hh"
30#include "WM_types.hh"
31
32/* -------------------------------------------------------------------- */
46
51
64
65bool ui_but_is_interactive_ex(const uiBut *but, const bool labeledit, const bool for_tooltip)
66{
67 /* NOTE: #UI_BTYPE_LABEL is included for highlights, this allows drags. */
69 if (for_tooltip) {
70 /* It's important labels are considered interactive for the purpose of showing tooltip. */
71 if (!ui_but_drag_is_draggable(but) && but->tip_func == nullptr &&
72 (but->tip == nullptr || but->tip[0] == '\0'))
73 {
74 return false;
75 }
76 }
77 else {
78 if (!ui_but_drag_is_draggable(but)) {
79 return false;
80 }
81 }
82 }
83
85 return false;
86 }
87 if (but->flag & UI_HIDDEN) {
88 return false;
89 }
90 if (but->flag & UI_SCROLLED) {
91 return false;
92 }
93 if ((but->type == UI_BTYPE_TEXT) &&
95 {
96 return false;
97 }
98 if ((but->type == UI_BTYPE_LISTROW) && labeledit) {
99 return false;
100 }
101 if (but->type == UI_BTYPE_VIEW_ITEM) {
102 const uiButViewItem *but_item = static_cast<const uiButViewItem *>(but);
103 return but_item->view_item->is_interactive();
104 }
105
106 return true;
107}
108
109bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
110{
111 return ui_but_is_interactive_ex(but, labeledit, false);
112}
113
114bool UI_but_is_utf8(const uiBut *but)
115{
116 if (but->rnaprop) {
117 const int subtype = RNA_property_subtype(but->rnaprop);
119 }
120 return !(but->flag & UI_BUT_NO_UTF8);
121}
122
123#ifdef USE_UI_POPOVER_ONCE
125{
127}
128#endif
129
131{
132 return (but->rnapoin.data && but->rnaprop && RNA_property_array_check(but->rnaprop));
133}
134
136bool UI_but_is_tool(const uiBut *but)
137{
138 /* very evil! */
139 if (but->optype != nullptr) {
140 if (g_ot_tool_set_by_id == nullptr) {
141 g_ot_tool_set_by_id = WM_operatortype_find("WM_OT_tool_set_by_id", false);
142 }
143 if (but->optype == g_ot_tool_set_by_id) {
144 return true;
145 }
146 }
147 return false;
148}
149
151{
152 return (but->drawflag & UI_BUT_HAS_TOOLTIP_LABEL) != 0;
153}
154
155int ui_but_icon(const uiBut *but)
156{
157 if (!(but->flag & UI_HAS_ICON)) {
158 return ICON_NONE;
159 }
160
161 /* Consecutive icons can be toggle between. */
162 if (but->drawflag & UI_BUT_ICON_REVERSE) {
163 return but->icon - but->iconadd;
164 }
165 return but->icon + but->iconadd;
166}
167
170/* -------------------------------------------------------------------- */
174void ui_but_pie_dir(RadialDirection dir, float vec[2])
175{
176 float angle;
177
179
180 angle = DEG2RADF(float(ui_radial_dir_to_angle[dir]));
181 vec[0] = cosf(angle);
182 vec[1] = sinf(angle);
183}
184
185static bool ui_but_isect_pie_seg(const uiBlock *block, const uiBut *but)
186{
187 if (block->pie_data.flags & UI_PIE_INVALID_DIR) {
188 return false;
189 }
190
191 /* Plus/minus 45 degrees: `cosf(DEG2RADF(45)) == M_SQRT1_2`. */
192 const float angle_4th_cos = M_SQRT1_2;
193 /* Plus/minus 22.5 degrees: `cosf(DEG2RADF(22.5))`. */
194 const float angle_8th_cos = 0.9238795f;
195
196 /* Use a large bias so edge-cases fall back to comparing with the adjacent direction. */
197 const float eps_bias = 1e-4;
198
199 float but_dir[2];
200 ui_but_pie_dir(but->pie_dir, but_dir);
201
202 const float angle_but_cos = dot_v2v2(but_dir, block->pie_data.pie_dir);
203 /* Outside range (with bias). */
204 if (angle_but_cos < angle_4th_cos - eps_bias) {
205 return false;
206 }
207 /* Inside range (with bias). */
208 if (angle_but_cos > angle_8th_cos + eps_bias) {
209 return true;
210 }
211
212 /* Check if adjacent direction is closer (with tie breaker). */
213 RadialDirection dir_adjacent_8th, dir_adjacent_4th;
214 if (angle_signed_v2v2(but_dir, block->pie_data.pie_dir) < 0.0f) {
215 dir_adjacent_8th = UI_RADIAL_DIRECTION_PREV(but->pie_dir);
216 dir_adjacent_4th = UI_RADIAL_DIRECTION_PREV(dir_adjacent_8th);
217 }
218 else {
219 dir_adjacent_8th = UI_RADIAL_DIRECTION_NEXT(but->pie_dir);
220 dir_adjacent_4th = UI_RADIAL_DIRECTION_NEXT(dir_adjacent_8th);
221 }
222
223 const bool has_8th_adjacent = block->pie_data.pie_dir_mask & (1 << int(dir_adjacent_8th));
224
225 /* Compare with the adjacent direction (even if there is no button). */
226 const RadialDirection dir_adjacent = has_8th_adjacent ? dir_adjacent_8th : dir_adjacent_4th;
227 float but_dir_adjacent[2];
228 ui_but_pie_dir(dir_adjacent, but_dir_adjacent);
229
230 const float angle_adjacent_cos = dot_v2v2(but_dir_adjacent, block->pie_data.pie_dir);
231
232 /* Tie breaker, so one of the buttons is always selected. */
233 if (UNLIKELY(angle_but_cos == angle_adjacent_cos)) {
234 return but->pie_dir > dir_adjacent;
235 }
236 return angle_but_cos > angle_adjacent_cos;
237}
238
239bool ui_but_contains_pt(const uiBut *but, float mx, float my)
240{
241 return BLI_rctf_isect_pt(&but->rect, mx, my);
242}
243
244bool ui_but_contains_rect(const uiBut *but, const rctf *rect)
245{
246 return BLI_rctf_isect(&but->rect, rect, nullptr);
247}
248
249bool ui_but_contains_point_px(const uiBut *but, const ARegion *region, const int xy[2])
250{
251 uiBlock *block = but->block;
252 if (!ui_region_contains_point_px(region, xy)) {
253 return false;
254 }
255
256 float mx = xy[0], my = xy[1];
257 ui_window_to_block_fl(region, block, &mx, &my);
258
259 if (but->pie_dir != UI_RADIAL_NONE) {
260 if (!ui_but_isect_pie_seg(block, but)) {
261 return false;
262 }
263 }
264 else if (!ui_but_contains_pt(but, mx, my)) {
265 return false;
266 }
267
268 return true;
269}
270
271bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEvent *event)
272{
273 rcti rect;
274 int x = event->xy[0], y = event->xy[1];
275
276 ui_window_to_block(region, but->block, &x, &y);
277
278 BLI_rcti_rctf_copy(&rect, &but->rect);
279
280 if (but->dragflag & UI_BUT_DRAG_FULL_BUT) {
281 /* use button size itself */
282 }
283 else if (but->drawflag & UI_BUT_ICON_LEFT) {
284 rect.xmax = rect.xmin + BLI_rcti_size_y(&rect);
285 }
286 else {
287 const int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect);
288 rect.xmin += delta / 2;
289 rect.xmax -= delta / 2;
290 }
291
292 return BLI_rcti_isect_pt(&rect, x, y);
293}
294
295static uiBut *ui_but_find(const ARegion *region,
296 const uiButFindPollFn find_poll,
297 const void *find_custom_data)
298{
299 LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
300 LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
301 if (find_poll && find_poll(but, find_custom_data) == false) {
302 continue;
303 }
304 return but;
305 }
306 }
307
308 return nullptr;
309}
310
312 const int xy[2],
313 const bool labeledit,
314 const bool for_tooltip,
315 const uiButFindPollFn find_poll,
316 const void *find_custom_data)
317{
318 uiBut *butover = nullptr;
319
320 if (!ui_region_contains_point_px(region, xy)) {
321 return nullptr;
322 }
323 LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
324 float mx = xy[0], my = xy[1];
325 ui_window_to_block_fl(region, block, &mx, &my);
326
327 LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
328 if (find_poll && find_poll(but, find_custom_data) == false) {
329 continue;
330 }
331 if (ui_but_is_interactive_ex(but, labeledit, for_tooltip)) {
332 if (but->pie_dir != UI_RADIAL_NONE) {
333 if (ui_but_isect_pie_seg(block, but)) {
334 butover = but;
335 break;
336 }
337 }
338 else if (ui_but_contains_pt(but, mx, my)) {
339 butover = but;
340 break;
341 }
342 }
343 }
344
345 /* CLIP_EVENTS prevents the event from reaching other blocks */
346 if (block->flag & UI_BLOCK_CLIP_EVENTS) {
347 /* check if mouse is inside block */
348 if (BLI_rctf_isect_pt(&block->rect, mx, my)) {
349 break;
350 }
351 }
352 }
353
354 return butover;
355}
356
357uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event)
358{
360 region, event->xy, event->modifier & KM_CTRL, false, nullptr, nullptr);
361}
362
363uiBut *ui_but_find_rect_over(const ARegion *region, const rcti *rect_px)
364{
365 if (!ui_region_contains_rect_px(region, rect_px)) {
366 return nullptr;
367 }
368
369 /* Currently no need to expose this at the moment. */
370 const bool labeledit = true;
371 rctf rect_px_fl;
372 BLI_rctf_rcti_copy(&rect_px_fl, rect_px);
373 uiBut *butover = nullptr;
374
375 LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
376 rctf rect_block;
377 ui_window_to_block_rctf(region, block, &rect_block, &rect_px_fl);
378
379 LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
380 if (ui_but_is_interactive(but, labeledit)) {
381 /* No pie menu support. */
382 BLI_assert(but->pie_dir == UI_RADIAL_NONE);
383 if (ui_but_contains_rect(but, &rect_block)) {
384 butover = but;
385 break;
386 }
387 }
388 }
389
390 /* CLIP_EVENTS prevents the event from reaching other blocks */
391 if (block->flag & UI_BLOCK_CLIP_EVENTS) {
392 /* check if mouse is inside block */
393 if (BLI_rctf_isect(&block->rect, &rect_block, nullptr)) {
394 break;
395 }
396 }
397 }
398 return butover;
399}
400
401uiBut *ui_list_find_mouse_over_ex(const ARegion *region, const int xy[2])
402{
403 if (!ui_region_contains_point_px(region, xy)) {
404 return nullptr;
405 }
406 LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
407 float mx = xy[0], my = xy[1];
408 ui_window_to_block_fl(region, block, &mx, &my);
409 LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
410 if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) {
411 return but;
412 }
413 }
414 }
415
416 return nullptr;
417}
418
419uiBut *ui_list_find_mouse_over(const ARegion *region, const wmEvent *event)
420{
421 if (event == nullptr) {
422 /* If there is no info about the mouse, just act as if there is nothing underneath it. */
423 return nullptr;
424 }
425 return ui_list_find_mouse_over_ex(region, event->xy);
426}
427
428uiList *UI_list_find_mouse_over(const ARegion *region, const wmEvent *event)
429{
430 uiBut *list_but = ui_list_find_mouse_over(region, event);
431 if (!list_but) {
432 return nullptr;
433 }
434
435 return static_cast<uiList *>(list_but->custom_data);
436}
437
438static bool ui_list_contains_row(const uiBut *listbox_but, const uiBut *listrow_but)
439{
440 BLI_assert(listbox_but->type == UI_BTYPE_LISTBOX);
441 BLI_assert(listrow_but->type == UI_BTYPE_LISTROW);
442 /* The list box and its rows have the same RNA data (active data pointer/prop). */
443 return ui_but_rna_equals(listbox_but, listrow_but);
444}
445
446static bool ui_but_is_listbox_with_row(const uiBut *but, const void *customdata)
447{
448 const uiBut *row_but = static_cast<const uiBut *>(customdata);
449 return (but->type == UI_BTYPE_LISTBOX) && ui_list_contains_row(but, row_but);
450}
451
452uiBut *ui_list_find_from_row(const ARegion *region, const uiBut *row_but)
453{
454 return ui_but_find(region, ui_but_is_listbox_with_row, row_but);
455}
456
457static bool ui_but_is_listrow(const uiBut *but, const void * /*customdata*/)
458{
459 return but->type == UI_BTYPE_LISTROW;
460}
461
462uiBut *ui_list_row_find_mouse_over(const ARegion *region, const int xy[2])
463{
464 return ui_but_find_mouse_over_ex(region, xy, false, false, ui_but_is_listrow, nullptr);
465}
466
471
472static bool ui_but_is_listrow_at_index(const uiBut *but, const void *customdata)
473{
474 const ListRowFindIndexData *find_data = static_cast<const ListRowFindIndexData *>(customdata);
475
476 return ui_but_is_listrow(but, nullptr) && ui_list_contains_row(find_data->listbox, but) &&
477 (but->hardmax == find_data->index);
478}
479
480uiBut *ui_list_row_find_index(const ARegion *region, const int index, uiBut *listbox)
481{
482 BLI_assert(listbox->type == UI_BTYPE_LISTBOX);
483 ListRowFindIndexData data = {};
484 data.index = index;
485 data.listbox = listbox;
486 return ui_but_find(region, ui_but_is_listrow_at_index, &data);
487}
488
489static bool ui_but_is_view_item_fn(const uiBut *but, const void * /*customdata*/)
490{
491 return but->type == UI_BTYPE_VIEW_ITEM;
492}
493
494uiBut *ui_view_item_find_mouse_over(const ARegion *region, const int xy[2])
495{
496 return ui_but_find_mouse_over_ex(region, xy, false, false, ui_but_is_view_item_fn, nullptr);
497}
498
499static bool ui_but_is_active_view_item(const uiBut *but, const void * /*customdata*/)
500{
501 if (but->type != UI_BTYPE_VIEW_ITEM) {
502 return false;
503 }
504
505 const uiButViewItem *view_item_but = (const uiButViewItem *)but;
506 return view_item_but->view_item->is_active();
507}
508
510{
511 return ui_but_find(region, ui_but_is_active_view_item, nullptr);
512}
513
515{
516 return ui_but_find(
517 region,
518 [](const uiBut *but, const void * /*find_custom_data*/) {
519 if (but->type != UI_BTYPE_VIEW_ITEM) {
520 return false;
521 }
522
523 const uiButViewItem *view_item_but = static_cast<const uiButViewItem *>(but);
524 return view_item_but->view_item->is_search_highlight();
525 },
526 nullptr);
527}
528
531/* -------------------------------------------------------------------- */
536{
537 while (but->prev) {
538 but = but->prev;
539 if (ui_but_is_editable(but)) {
540 return but;
541 }
542 }
543 return nullptr;
544}
545
547{
548 while (but->next) {
549 but = but->next;
550 if (ui_but_is_editable(but)) {
551 return but;
552 }
553 }
554 return nullptr;
555}
556
558{
559 LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
560 if (ui_but_is_editable(but)) {
561 return but;
562 }
563 }
564 return nullptr;
565}
566
568{
569 uiBut *but = static_cast<uiBut *>(block->buttons.last);
570 while (but) {
571 if (ui_but_is_editable(but)) {
572 return but;
573 }
574 but = but->prev;
575 }
576 return nullptr;
577}
578
580{
581 if (U.uiflag & USER_CONTINUOUS_MOUSE) {
582 if (ELEM(but->type,
590 {
591 return true;
592 }
593 }
594
595 return false;
596}
597
599{
600 return but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD);
601}
602
605/* -------------------------------------------------------------------- */
610{
611 if (but->flag & UI_BUT_HAS_SEP_CHAR) {
612 const size_t sep_index = but->drawstr.find(UI_SEP_CHAR);
613 if (sep_index != std::string::npos) {
614 return sep_index;
615 }
616 }
617 return but->drawstr.size();
618}
619
621{
622 size_t str_len_clip = ui_but_drawstr_len_without_sep_char(but);
623 return blender::StringRef(but->drawstr).substr(0, str_len_clip);
624}
625
627{
628 if (but->tip == nullptr) {
629 return 0;
630 }
631 const char *str_sep = BLI_strchr_or_end(but->tip, '\n');
632 return (str_sep - but->tip);
633}
634
637/* -------------------------------------------------------------------- */
642{
643 LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
644 if (but->active) {
645 return but;
646 }
647 }
648
649 return nullptr;
650}
651
652bool ui_block_is_menu(const uiBlock *block)
653{
654 return (((block->flag & UI_BLOCK_LOOP) != 0) &&
655 /* non-menu popups use keep-open, so check this is off */
656 ((block->flag & UI_BLOCK_KEEP_OPEN) == 0));
657}
658
659bool ui_block_is_popover(const uiBlock *block)
660{
661 return (block->flag & UI_BLOCK_POPOVER) != 0;
662}
663
665{
666 return ((block->flag & UI_BLOCK_PIE_MENU) != 0);
667}
668
670{
671 return (ui_block_is_menu(block) || ui_block_is_popover(block) || ui_block_is_pie_menu(block));
672}
673
674static const uiBut *ui_but_next_non_separator(const uiBut *but)
675{
676 for (; but; but = but->next) {
678 return but;
679 }
680 }
681 return nullptr;
682}
683
684bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title)
685{
686 const uiBut *but = static_cast<const uiBut *>(block->buttons.first);
687 if (skip_title) {
688 /* Skip the first label, since popups often have a title,
689 * we may want to consider the block empty in this case. */
690 but = ui_but_next_non_separator(but);
691 if (but && but->type == UI_BTYPE_LABEL) {
692 but = but->next;
693 }
694 }
695 return (ui_but_next_non_separator(but) == nullptr);
696}
697
698bool UI_block_is_empty(const uiBlock *block)
699{
700 return UI_block_is_empty_ex(block, false);
701}
702
704{
705 if (ui_block_is_menu(block) && !ui_block_is_pie_menu(block)) {
706 const uiBut *but = static_cast<const uiBut *>(block->buttons.last);
707 return (but && !ELEM(but->type, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR));
708 }
709 return true;
710}
711
713{
714 LISTBASE_FOREACH (const uiBut *, but, &block->buttons) {
715 if ((but->flag & UI_BUT_ACTIVE_DEFAULT) && ((but->flag & UI_HIDDEN) == 0)) {
716 return true;
717 }
718 }
719 return false;
720}
721
724/* -------------------------------------------------------------------- */
728uiBlock *ui_block_find_mouse_over_ex(const ARegion *region, const int xy[2], bool only_clip)
729{
730 if (!ui_region_contains_point_px(region, xy)) {
731 return nullptr;
732 }
733 LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
734 if (only_clip) {
735 if ((block->flag & UI_BLOCK_CLIP_EVENTS) == 0) {
736 continue;
737 }
738 }
739 float mx = xy[0], my = xy[1];
740 ui_window_to_block_fl(region, block, &mx, &my);
741 if (BLI_rctf_isect_pt(&block->rect, mx, my)) {
742 return block;
743 }
744 }
745 return nullptr;
746}
747
748uiBlock *ui_block_find_mouse_over(const ARegion *region, const wmEvent *event, bool only_clip)
749{
750 return ui_block_find_mouse_over_ex(region, event->xy, only_clip);
751}
752
755/* -------------------------------------------------------------------- */
760{
761 LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
762 uiBut *but = ui_block_active_but_get(block);
763 if (but) {
764 return but;
765 }
766 }
767
768 return nullptr;
769}
770
771uiBut *ui_region_find_first_but_test_flag(ARegion *region, int flag_include, int flag_exclude)
772{
773 LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
774 LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
775 if (((but->flag & flag_include) == flag_include) && ((but->flag & flag_exclude) == 0)) {
776 return but;
777 }
778 }
779 }
780
781 return nullptr;
782}
783
786/* -------------------------------------------------------------------- */
790bool ui_region_contains_point_px(const ARegion *region, const int xy[2])
791{
792 rcti winrct;
793 ui_region_winrct_get_no_margin(region, &winrct);
794 if (!BLI_rcti_isect_pt_v(&winrct, xy)) {
795 return false;
796 }
797
798 /* also, check that with view2d, that the mouse is not over the scroll-bars
799 * NOTE: care is needed here, since the mask rect may include the scroll-bars
800 * even when they are not visible, so we need to make a copy of the mask to
801 * use to check
802 */
803 if (region->v2d.mask.xmin != region->v2d.mask.xmax) {
804 const View2D *v2d = &region->v2d;
805 int mx = xy[0], my = xy[1];
806
807 ui_window_to_region(region, &mx, &my);
808 if (!BLI_rcti_isect_pt(&v2d->mask, mx, my) ||
809 UI_view2d_mouse_in_scrollers(region, &region->v2d, xy))
810 {
811 return false;
812 }
813 }
814
815 return true;
816}
817
818bool ui_region_contains_rect_px(const ARegion *region, const rcti *rect_px)
819{
820 rcti winrct;
821 ui_region_winrct_get_no_margin(region, &winrct);
822 if (!BLI_rcti_isect(&winrct, rect_px, nullptr)) {
823 return false;
824 }
825
826 /* See comment in 'ui_region_contains_point_px' */
827 if (region->v2d.mask.xmin != region->v2d.mask.xmax) {
828 const View2D *v2d = &region->v2d;
829 rcti rect_region;
830 ui_window_to_region_rcti(region, &rect_region, rect_px);
831 if (!BLI_rcti_isect(&v2d->mask, &rect_region, nullptr) ||
832 UI_view2d_rect_in_scrollers(region, &region->v2d, rect_px))
833 {
834 return false;
835 }
836 }
837
838 return true;
839}
840
843/* -------------------------------------------------------------------- */
848{
849 LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
850 rcti winrct;
851
852 ui_region_winrct_get_no_margin(region, &winrct);
853
854 if (BLI_rcti_isect_pt_v(&winrct, xy)) {
855 return region;
856 }
857 }
858 return nullptr;
859}
860
862{
863 return ui_screen_region_find_mouse_over_ex(screen, event->xy);
864}
865
868/* -------------------------------------------------------------------- */
876
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
#define M_SQRT1_2
#define DEG2RADF(_deg)
float angle_signed_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest)
bool BLI_rcti_isect_pt(const struct rcti *rect, int x, int y)
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
bool BLI_rctf_isect_pt(const struct rctf *rect, float x, float y)
void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src)
void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src)
char char size_t char const char * BLI_strchr_or_end(const char *str, char ch) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
Definition string.c:927
#define UNLIKELY(x)
#define ELEM(...)
@ USER_CONTINUOUS_MOUSE
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
@ PROP_BYTESTRING
Definition RNA_types.hh:143
@ PROP_FILENAME
Definition RNA_types.hh:141
@ PROP_PASSWORD
Definition RNA_types.hh:146
@ PROP_DIRPATH
Definition RNA_types.hh:140
@ PROP_FILEPATH
Definition RNA_types.hh:139
@ UI_EMBOSS_NONE
@ UI_EMBOSS_NONE_OR_STATUS
@ UI_BLOCK_CLIP_EVENTS
@ UI_BLOCK_LOOP
@ UI_BLOCK_PIE_MENU
@ UI_BLOCK_KEEP_OPEN
@ UI_BLOCK_POPOVER
#define UI_SEP_CHAR
@ UI_BUT_DRAG_FULL_BUT
@ UI_BTYPE_BUT
@ UI_BTYPE_TOGGLE
@ UI_BTYPE_PROGRESS
@ UI_BTYPE_LISTBOX
@ UI_BTYPE_ROUNDBOX
@ UI_BTYPE_TOGGLE_N
@ UI_BTYPE_NUM_SLIDER
@ UI_BTYPE_HSVCIRCLE
@ UI_BTYPE_LISTROW
@ UI_BTYPE_TEXT
@ UI_BTYPE_BUT_TOGGLE
@ UI_BTYPE_VIEW_ITEM
@ UI_BTYPE_HSVCUBE
@ UI_BTYPE_PREVIEW_TILE
@ UI_BTYPE_LABEL
@ UI_BTYPE_CURVE
@ UI_BTYPE_ICON_TOGGLE_N
@ UI_BTYPE_DECORATOR
@ UI_BTYPE_ROW
@ UI_BTYPE_SEARCH_MENU
@ UI_BTYPE_SEPR_LINE
@ UI_BTYPE_CHECKBOX_N
@ UI_BTYPE_SEPR
@ UI_BTYPE_NUM
@ UI_BTYPE_CURVEPROFILE
@ UI_BTYPE_TRACK_PREVIEW
@ UI_BTYPE_CHECKBOX
@ UI_BTYPE_ICON_TOGGLE
@ UI_BUT_ICON_LEFT
@ UI_BUT_HAS_TOOLTIP_LABEL
@ UI_BUT_ICON_REVERSE
@ UI_BUT_ACTIVE_DEFAULT
@ UI_BUT_NO_UTF8
@ UI_BUT_HAS_SEP_CHAR
char char UI_view2d_mouse_in_scrollers(const ARegion *region, const View2D *v2d, const int xy[2]) ATTR_NONNULL(1
char char char char UI_view2d_rect_in_scrollers(const ARegion *region, const View2D *v2d, const rcti *rect) ATTR_NONNULL(1
@ KM_CTRL
Definition WM_types.hh:256
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
unsigned int U
Definition btGjkEpa3.h:78
constexpr StringRef substr(int64_t start, int64_t size) const
#define sinf(x)
#define cosf(x)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void ui_window_to_block(const ARegion *region, const uiBlock *block, int *x, int *y)
Definition interface.cc:221
const short ui_radial_dir_to_angle[8]
void ui_window_to_region_rcti(const ARegion *region, rcti *rect_dst, const rcti *rct_src)
Definition interface.cc:238
void ui_window_to_region(const ARegion *region, int *x, int *y)
Definition interface.cc:232
void ui_window_to_block_fl(const ARegion *region, const uiBlock *block, float *x, float *y)
Definition interface.cc:184
bool ui_but_rna_equals(const uiBut *a, const uiBut *b)
Definition interface.cc:703
void ui_window_to_block_rctf(const ARegion *region, const uiBlock *block, rctf *rct_dst, const rctf *rct_src)
Definition interface.cc:211
void ui_region_winrct_get_no_margin(const ARegion *region, rcti *r_rect)
Definition interface.cc:334
bool ui_but_drag_is_draggable(const uiBut *but)
RadialDirection
@ UI_RADIAL_NONE
#define UI_RADIAL_DIRECTION_NEXT(dir)
@ UI_PIE_INVALID_DIR
bool(*)(const uiBut *but, const void *customdata) uiButFindPollFn
#define UI_RADIAL_DIRECTION_PREV(dir)
@ UI_HIDDEN
@ UI_SCROLLED
@ UI_HAS_ICON
uiBut * ui_list_find_mouse_over(const ARegion *region, const wmEvent *event)
size_t ui_but_drawstr_len_without_sep_char(const uiBut *but)
uiList * UI_list_find_mouse_over(const ARegion *region, const wmEvent *event)
static bool ui_but_is_listrow_at_index(const uiBut *but, const void *customdata)
uiBut * ui_block_active_but_get(const uiBlock *block)
bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title)
blender::StringRef ui_but_drawstr_without_sep_char(const uiBut *but)
bool UI_block_can_add_separator(const uiBlock *block)
bool ui_but_contains_point_px(const uiBut *but, const ARegion *region, const int xy[2])
uiBut * ui_list_find_from_row(const ARegion *region, const uiBut *row_but)
bool ui_block_is_popup_any(const uiBlock *block)
static uiBut * ui_but_find(const ARegion *region, const uiButFindPollFn find_poll, const void *find_custom_data)
bool ui_but_is_toggle(const uiBut *but)
bool ui_but_contains_pt(const uiBut *but, float mx, float my)
uiBut * ui_but_find_mouse_over_ex(const ARegion *region, const int xy[2], const bool labeledit, const bool for_tooltip, const uiButFindPollFn find_poll, const void *find_custom_data)
uiBut * ui_but_next(uiBut *but)
bool ui_but_contains_rect(const uiBut *but, const rctf *rect)
bool ui_but_contains_password(const uiBut *but)
ARegion * ui_screen_region_find_mouse_over(bScreen *screen, const wmEvent *event)
uiBut * ui_but_find_mouse_over(const ARegion *region, const wmEvent *event)
bool UI_but_is_utf8(const uiBut *but)
size_t ui_but_tip_len_only_first_line(const uiBut *but)
bool UI_block_is_empty(const uiBlock *block)
uiBut * ui_view_item_find_active(const ARegion *region)
static const uiBut * ui_but_next_non_separator(const uiBut *but)
static wmOperatorType * g_ot_tool_set_by_id
static bool ui_list_contains_row(const uiBut *listbox_but, const uiBut *listrow_but)
void ui_interface_tag_script_reload_queries()
uiBut * ui_list_row_find_mouse_over(const ARegion *region, const int xy[2])
static bool ui_but_is_active_view_item(const uiBut *but, const void *)
static bool ui_but_isect_pie_seg(const uiBlock *block, const uiBut *but)
bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEvent *event)
bool ui_block_is_popover(const uiBlock *block)
uiBlock * ui_block_find_mouse_over_ex(const ARegion *region, const int xy[2], bool only_clip)
bool ui_but_is_editable(const uiBut *but)
ARegion * ui_screen_region_find_mouse_over_ex(bScreen *screen, const int xy[2])
bool ui_block_is_pie_menu(const uiBlock *block)
bool ui_but_is_cursor_warp(const uiBut *but)
bool UI_block_has_active_default_button(const uiBlock *block)
uiBut * ui_view_item_find_mouse_over(const ARegion *region, const int xy[2])
bool ui_region_contains_point_px(const ARegion *region, const int xy[2])
uiBut * ui_view_item_find_search_highlight(const ARegion *region)
uiBlock * ui_block_find_mouse_over(const ARegion *region, const wmEvent *event, bool only_clip)
uiBut * ui_region_find_first_but_test_flag(ARegion *region, int flag_include, int flag_exclude)
bool ui_but_is_interactive_ex(const uiBut *but, const bool labeledit, const bool for_tooltip)
uiBut * ui_but_prev(uiBut *but)
static bool ui_but_is_view_item_fn(const uiBut *but, const void *)
uiBut * ui_list_find_mouse_over_ex(const ARegion *region, const int xy[2])
bool ui_block_is_menu(const uiBlock *block)
bool ui_region_contains_rect_px(const ARegion *region, const rcti *rect_px)
bool ui_but_is_popover_once_compat(const uiBut *but)
bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
void ui_but_pie_dir(RadialDirection dir, float vec[2])
uiBut * ui_region_find_active_but(ARegion *region)
int ui_but_icon(const uiBut *but)
uiBut * ui_but_last(uiBlock *block)
static bool ui_but_is_listbox_with_row(const uiBut *but, const void *customdata)
bool ui_but_is_editable_as_text(const uiBut *but)
bool UI_but_is_tool(const uiBut *but)
uiBut * ui_but_first(uiBlock *block)
uiBut * ui_but_find_rect_over(const ARegion *region, const rcti *rect_px)
static bool ui_but_is_listrow(const uiBut *but, const void *)
uiBut * ui_list_row_find_index(const ARegion *region, const int index, uiBut *listbox)
bool UI_but_has_tooltip_label(const uiBut *but)
bool ui_but_has_array_value(const uiBut *but)
bool RNA_property_array_check(PropertyRNA *prop)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
void * last
void * first
void * data
Definition RNA_types.hh:42
int xmin
int xmax
PieMenuData pie_data
ListBase buttons
blender::ui::AbstractViewItem * view_item
const char * tip
void * custom_data
RadialDirection pie_dir
PropertyRNA * rnaprop
wmOperatorType * optype
eButType type
uiBlock * block
eUIEmbossType emboss
uiButToolTipFunc tip_func
std::string drawstr
uiBut * next
uiBut * prev
BIFIconID icon
PointerRNA rnapoin
int xy[2]
Definition WM_types.hh:726
uint8_t modifier
Definition WM_types.hh:739
int xy[2]
Definition wm_draw.cc:170
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)