73 if (!handle->refresh) {
79 butrct.
ymax +=
U.pixelsize;
82 butrct.
xmin -=
U.pixelsize;
86 handle->prev_butrct = butrct;
90 butrct = handle->prev_butrct;
115 const float max_radius = (0.5f *
U.widget_unit);
117 if (delta >= 0 && delta < max_radius) {
120 if (bt->rect.xmax == block->
rect.
xmax) {
121 bt->rect.xmax -= delta;
133 body.start_y /= block->
aspect;
134 body.end_y /= block->
aspect;
137 header.start_y /= block->
aspect;
138 header.end_y /= block->
aspect;
152 max_ff(size_x, handle->max_size_x),
153 max_ff(size_y, handle->max_size_y),
156 short dir1 = 0, dir2 = 0;
158 if (!handle->refresh) {
159 bool left =
false, right =
false, top =
false, down =
false;
162 if (butrct.
xmin - max_size[0] + center_x > 0.0f) {
165 if (butrct.
xmax + max_size[0] - center_x < win_size[0]) {
168 if (butrct.
ymin - max_size[1] + center_y > 0.0f) {
171 if (butrct.
ymax + max_size[1] - center_y < win_size[1]) {
175 if (top == 0 && down == 0) {
176 if (butrct.
ymin - max_size[1] < win_size[1] - butrct.
ymax - max_size[1]) {
234 handle->prev_dir1 = dir1;
235 handle->prev_dir2 = dir2;
240 dir1 = handle->prev_dir1;
241 dir2 = handle->prev_dir2;
245 float offset_x = 0, offset_y = 0;
248 const float offset_overlap =
max_ff(
U.pixelsize, 1.0f);
251 offset_x = (butrct.
xmin - block->
rect.
xmax) + offset_overlap;
260 offset_x = (butrct.
xmax - block->
rect.
xmin) - offset_overlap;
269 offset_y = (butrct.
ymax - block->
rect.
ymin) - offset_overlap;
289 offset_y = (butrct.
ymin - block->
rect.
ymax) + offset_overlap;
335 if (midx < block->rect.xmin) {
350 if (midy < block->rect.ymin) {
365 if (dir1 && (dir1 & block->
direction) == 0) {
376 const bool off_screen_left = (block->
rect.
xmin < 0);
377 const bool off_screen_right = (block->
rect.
xmax > win_size[0]);
379 if (fully_aligned_with_button) {
383 else if (off_screen_left || off_screen_right) {
392 block->
direction = no_2nd_dir ? dir1 : (dir1 | dir2);
396 uiSafetyRct *saferct = MEM_cnew<uiSafetyRct>(__func__);
421 region->
do_draw &= ~RGN_REFRESH_UI;
425 if (handle->can_refresh) {
426 handle_ctx_area = handle->ctx_area;
427 handle_ctx_region = handle->ctx_region;
429 if (handle_ctx_area) {
432 if (handle_ctx_region) {
436 uiBut *but = handle->popup_create_vars.but;
437 ARegion *butregion = handle->popup_create_vars.butregion;
478 const float xmin_orig = block->
rect.
xmin;
488 if (block->
rect.
xmax > win_size[0] - margin) {
489 const float xofs = win_size[0] - margin - block->
rect.
xmax;
495 const float xofs = (margin - block->
rect.
xmin);
508 const float xofs = block->
rect.
xmin - xmin_orig;
510 bt->rect.xmin += xofs;
511 bt->rect.xmax += xofs;
520 bt->flag &= ~UI_SCROLLED;
529 if (bt->rect.ymin < block->
rect.
ymin) {
533 if (bt->rect.ymax > block->
rect.
ymax) {
566 if (
BLI_findindex(&screen->regionbase, handle->region) == -1) {
569 if (
BLI_findindex(&screen->regionbase, handle->region) != -1) {
591 if (handle->scrolltimer) {
598 if (!panel || dy == 0.0f) {
606 headcer.start_y += dy;
624 block->
panel = panel;
635 ARegion *region = handle->region;
639 void *arg = handle->popup_create_vars.arg;
641 uiBlock *block_old =
static_cast<uiBlock *
>(region->uiblocks.first);
643 handle->refresh = (block_old !=
nullptr);
645 BLI_assert(!handle->refresh || handle->can_refresh);
658 block = handle_create_func(C, handle, arg);
695 region->regiondata = handle;
698 if (but ==
nullptr) {
710 C, block, handle->popup_create_vars.event_xy, handle->popup_create_vars.event_xy);
721 uiSafetyRct *saferct = MEM_cnew<uiSafetyRct>(__func__);
737 x_offset += win_width - block->
rect.
xmin;
739 if (block->
rect.
xmax > win_size[0] - win_width) {
740 x_offset += win_size[0] - win_width - block->
rect.
xmax;
747 y_offset += win_width - block->
rect.
ymin;
749 if (block->
rect.
ymax > win_size[1] - win_width) {
750 y_offset += win_size[1] - win_width - block->
rect.
ymax;
755 if ((x_offset != 0) || (y_offset != 0)) {
761 if (
U.pie_initial_timeout > 0) {
766 region->winrct.xmin = 0;
767 region->winrct.xmax = win_size[0];
768 region->winrct.ymin = 0;
769 region->winrct.ymax = win_size[1];
774 if (
U.pie_animation_timeout > 0) {
786 const float unit_size =
U.widget_unit / block->
aspect;
797 if (handle->refresh && handle->prev_block_rect.ymax > block->
rect.
ymax) {
799 const float offset = handle->prev_block_rect.ymax - block->
rect.
ymax;
801 block->
rect.
ymin = handle->prev_block_rect.ymin;
805 handle->prev_block_rect = block->
rect;
811 region->winrct.xmax = block->
rect.
xmax + margin;
812 region->winrct.ymin = block->
rect.
ymin - margin;
820 ymin =
min_ff(ymin, bt->rect.ymin);
821 ymax =
max_ff(ymax, bt->rect.ymax);
824 const float scroll_min = std::min(block->
rect.
ymax - ymax - scroll_pad, 0.0f);
825 const float scroll_max = std::max(block->
rect.
ymin - ymin + scroll_pad, 0.0f);
826 handle->scrolloffset = std::clamp(handle->scrolloffset, scroll_min, scroll_max);
828 if (handle->scrolloffset != 0.0f) {
830 bt->rect.ymin += handle->scrolloffset;
831 bt->rect.ymax += handle->scrolloffset;
876 const bool can_refresh)
894 handle->can_refresh = can_refresh;
897 handle->popup_create_vars.create_func =
create_func;
898 handle->popup_create_vars.handle_create_func = handle_create_func;
899 handle->popup_create_vars.arg = arg;
900 handle->popup_create_vars.arg_free = arg_free;
901 handle->popup_create_vars.but = but;
902 handle->popup_create_vars.butregion = but ? butregion :
nullptr;
907 handle->region = region;
914 region->type = &type;
936 ARegion *region_popup_prev =
nullptr;
963 bool is_submenu =
false;
967 ARegion *region = handle->popup_create_vars.butregion;
968 if (region !=
nullptr) {
988 if (handle->popup_create_vars.arg_free) {
989 handle->popup_create_vars.arg_free(handle->popup_create_vars.arg);
992 if (handle->region->runtime.popup_block_panel) {
bScreen * CTX_wm_screen(const bContext *C)
ARegion * CTX_wm_region_popup(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
void CTX_wm_window_set(bContext *C, wmWindow *win)
void CTX_wm_area_set(bContext *C, ScrArea *area)
void CTX_wm_region_set(bContext *C, ARegion *region)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
void CTX_wm_region_popup_set(bContext *C, ARegion *region_popup)
void BKE_panel_free(Panel *panel)
Panel * BKE_panel_new(PanelType *panel_type)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
void BLI_rctf_translate(struct rctf *rect, float x, float y)
void BLI_rctf_union(struct rctf *rct_a, const struct rctf *rct_b)
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
void BLI_rcti_translate(struct rcti *rect, int x, int y)
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
void BLI_rctf_recenter(struct rctf *rect, float x, float y)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
void BLI_rctf_init_minmax(struct rctf *rect)
void ED_region_tag_refresh_ui(ARegion *region)
void ED_region_update_rect(ARegion *region)
void ED_region_floating_init(ARegion *region)
void ED_workspace_status_text(bContext *C, const char *str)
void ED_region_tag_redraw(ARegion *region)
Read Guarded memory(de)allocation.
void UI_block_update_from_old(const bContext *C, uiBlock *block)
void(*)(void *arg) uiFreeArgFunc
void UI_block_theme_style_set(uiBlock *block, char theme_style)
@ UI_BLOCK_NO_ACCELERATOR_KEYS
void UI_block_translate(uiBlock *block, float x, float y)
void UI_but_tooltip_timer_remove(bContext *C, uiBut *but)
uiBut * UI_context_active_but_get(const bContext *C)
@ UI_BLOCK_BOUNDS_POPUP_CENTER
void UI_block_draw(const bContext *C, uiBlock *block)
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
@ UI_BLOCK_THEME_STYLE_POPUP
void UI_blocklist_free_inactive(const bContext *C, ARegion *region)
uiBlock *(*)(bContext *C, ARegion *region, void *arg1) uiBlockCreateFunc
void UI_region_handlers_add(ListBase *handlers)
void ui_but_update(uiBut *but)
bool ui_but_menu_draw_as_popover(const uiBut *but)
void ui_block_to_window_rctf(const ARegion *region, const uiBlock *block, rctf *rct_dst, const rctf *rct_src)
float ui_block_calc_pie_segment(uiBlock *block, const float event_xy[2])
#define UI_POPUP_MENU_TOP
uiBlock *(*)(bContext *C, uiPopupBlockHandle *handle, void *arg1) uiBlockHandleCreateFunc
#define UI_MENU_SUBMENU_PADDING
@ UI_PIE_INITIAL_DIRECTION
bool ui_block_is_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT
#define UI_MENU_SCROLL_PAD
#define UI_MENU_SCROLL_ARROW
@ UI_BLOCK_CONTAINS_SUBMENU_BUT
ARegion * ui_region_temp_add(bScreen *screen)
void ui_region_temp_remove(bContext *C, bScreen *screen, ARegion *region)
void MEM_freeN(void *vmemh)
static PyObject * create_func(PyObject *, PyObject *args)
blender::Vector< LayoutPanelBody > bodies
blender::Vector< LayoutPanelHeader > headers
LayoutPanels layout_panels
struct Panel_Runtime * runtime
uiPopupBlockHandle * handle
eBlockBoundsCalc bounds_type
struct wmEvent * eventstate
struct wmEvent * event_last_handled
void WM_cursor_set(wmWindow *win, int curs)
void wmGetProjectionMatrix(float mat[4][4], const rcti *winrct)
blender::int2 WM_window_native_pixel_size(const wmWindow *win)
void WM_event_timer_remove(wmWindowManager *wm, wmWindow *, wmTimer *timer)
bScreen * WM_window_get_active_screen(const wmWindow *win)