Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface_region_popup.c
| Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| /** \name Utility Functions | /** \name Utility Functions | ||||
| * \{ */ | * \{ */ | ||||
| /** | /** | ||||
| * Translate any popup regions (so we can drag them). | * Translate any popup regions (so we can drag them). | ||||
| */ | */ | ||||
| void ui_popup_translate(ARegion *region, const int mdiff[2]) | void ui_popup_translate(ARegion *region, const int mdiff[2]) | ||||
| { | { | ||||
| uiBlock *block; | |||||
| BLI_rcti_translate(®ion->winrct, UNPACK2(mdiff)); | BLI_rcti_translate(®ion->winrct, UNPACK2(mdiff)); | ||||
| ED_region_update_rect(region); | ED_region_update_rect(region); | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| /* update blocks */ | /* update blocks */ | ||||
| for (block = region->uiblocks.first; block; block = block->next) { | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| uiPopupBlockHandle *handle = block->handle; | uiPopupBlockHandle *handle = block->handle; | ||||
| /* Make empty, will be initialized on next use, see T60608. */ | /* Make empty, will be initialized on next use, see T60608. */ | ||||
| BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0); | BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0); | ||||
| uiSafetyRct *saferct; | LISTBASE_FOREACH (uiSafetyRct *, saferct, &block->saferct) { | ||||
| for (saferct = block->saferct.first; saferct; saferct = saferct->next) { | |||||
| BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff)); | BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff)); | ||||
| BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff)); | BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* position block relative to but, result is in window space */ | /* position block relative to but, result is in window space */ | ||||
| static void ui_popup_block_position(wmWindow *window, | static void ui_popup_block_position(wmWindow *window, | ||||
| ▲ Show 20 Lines • Show All 282 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Menu Block Creation | /** \name Menu Block Creation | ||||
| * \{ */ | * \{ */ | ||||
| static void ui_block_region_refresh(const bContext *C, ARegion *region) | static void ui_block_region_refresh(const bContext *C, ARegion *region) | ||||
| { | { | ||||
| ScrArea *ctx_area = CTX_wm_area(C); | ScrArea *ctx_area = CTX_wm_area(C); | ||||
| ARegion *ctx_region = CTX_wm_region(C); | ARegion *ctx_region = CTX_wm_region(C); | ||||
| uiBlock *block; | |||||
| if (region->do_draw & RGN_REFRESH_UI) { | if (region->do_draw & RGN_REFRESH_UI) { | ||||
| ScrArea *handle_ctx_area; | ScrArea *handle_ctx_area; | ||||
| ARegion *handle_ctx_region; | ARegion *handle_ctx_region; | ||||
| uiBlock *block_next; | |||||
| region->do_draw &= ~RGN_REFRESH_UI; | region->do_draw &= ~RGN_REFRESH_UI; | ||||
| for (block = region->uiblocks.first; block; block = block_next) { | LISTBASE_FOREACH_MUTABLE (uiBlock *, block, ®ion->uiblocks) { | ||||
| block_next = block->next; | |||||
| uiPopupBlockHandle *handle = block->handle; | uiPopupBlockHandle *handle = block->handle; | ||||
| if (handle->can_refresh) { | if (handle->can_refresh) { | ||||
| handle_ctx_area = handle->ctx_area; | handle_ctx_area = handle->ctx_area; | ||||
| handle_ctx_region = handle->ctx_region; | handle_ctx_region = handle->ctx_region; | ||||
| if (handle_ctx_area) { | if (handle_ctx_area) { | ||||
| CTX_wm_area_set((bContext *)C, handle_ctx_area); | CTX_wm_area_set((bContext *)C, handle_ctx_area); | ||||
| Show All 10 Lines | static void ui_block_region_refresh(const bContext *C, ARegion *region) | ||||
| } | } | ||||
| CTX_wm_area_set((bContext *)C, ctx_area); | CTX_wm_area_set((bContext *)C, ctx_area); | ||||
| CTX_wm_region_set((bContext *)C, ctx_region); | CTX_wm_region_set((bContext *)C, ctx_region); | ||||
| } | } | ||||
| static void ui_block_region_draw(const bContext *C, ARegion *region) | static void ui_block_region_draw(const bContext *C, ARegion *region) | ||||
| { | { | ||||
| uiBlock *block; | LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { | ||||
| for (block = region->uiblocks.first; block; block = block->next) { | |||||
| UI_block_draw(C, block); | UI_block_draw(C, block); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Use to refresh centered popups on screen resizing (for splash). | * Use to refresh centered popups on screen resizing (for splash). | ||||
| */ | */ | ||||
| static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win), | static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win), | ||||
| Show All 13 Lines | case NC_WINDOW: { | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void ui_popup_block_clip(wmWindow *window, uiBlock *block) | static void ui_popup_block_clip(wmWindow *window, uiBlock *block) | ||||
| { | { | ||||
| uiBut *bt; | |||||
| const float xmin_orig = block->rect.xmin; | const float xmin_orig = block->rect.xmin; | ||||
| const int margin = UI_SCREEN_MARGIN; | const int margin = UI_SCREEN_MARGIN; | ||||
| int winx, winy; | int winx, winy; | ||||
| if (block->flag & UI_BLOCK_NO_WIN_CLIP) { | if (block->flag & UI_BLOCK_NO_WIN_CLIP) { | ||||
| return; | return; | ||||
| } | } | ||||
| Show All 17 Lines | if (block->rect.ymin < margin) { | ||||
| block->rect.ymin = margin; | block->rect.ymin = margin; | ||||
| } | } | ||||
| if (block->rect.ymax > winy - UI_POPUP_MENU_TOP) { | if (block->rect.ymax > winy - UI_POPUP_MENU_TOP) { | ||||
| block->rect.ymax = winy - UI_POPUP_MENU_TOP; | block->rect.ymax = winy - UI_POPUP_MENU_TOP; | ||||
| } | } | ||||
| /* ensure menu items draw inside left/right boundary */ | /* ensure menu items draw inside left/right boundary */ | ||||
| const float xofs = block->rect.xmin - xmin_orig; | const float xofs = block->rect.xmin - xmin_orig; | ||||
| for (bt = block->buttons.first; bt; bt = bt->next) { | LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { | ||||
| bt->rect.xmin += xofs; | bt->rect.xmin += xofs; | ||||
| bt->rect.xmax += xofs; | bt->rect.xmax += xofs; | ||||
| } | } | ||||
| } | } | ||||
| void ui_popup_block_scrolltest(uiBlock *block) | void ui_popup_block_scrolltest(uiBlock *block) | ||||
| { | { | ||||
| uiBut *bt; | |||||
| block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP); | block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP); | ||||
| for (bt = block->buttons.first; bt; bt = bt->next) { | LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { | ||||
| bt->flag &= ~UI_SCROLLED; | bt->flag &= ~UI_SCROLLED; | ||||
| } | } | ||||
| if (block->buttons.first == block->buttons.last) { | if (block->buttons.first == block->buttons.last) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* mark buttons that are outside boundary */ | /* mark buttons that are outside boundary */ | ||||
| for (bt = block->buttons.first; bt; bt = bt->next) { | LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { | ||||
| if (bt->rect.ymin < block->rect.ymin) { | if (bt->rect.ymin < block->rect.ymin) { | ||||
| bt->flag |= UI_SCROLLED; | bt->flag |= UI_SCROLLED; | ||||
| block->flag |= UI_BLOCK_CLIPBOTTOM; | block->flag |= UI_BLOCK_CLIPBOTTOM; | ||||
| } | } | ||||
| if (bt->rect.ymax > block->rect.ymax) { | if (bt->rect.ymax > block->rect.ymax) { | ||||
| bt->flag |= UI_SCROLLED; | bt->flag |= UI_SCROLLED; | ||||
| block->flag |= UI_BLOCK_CLIPTOP; | block->flag |= UI_BLOCK_CLIPTOP; | ||||
| } | } | ||||
| } | } | ||||
| /* mark buttons overlapping arrows, if we have them */ | /* mark buttons overlapping arrows, if we have them */ | ||||
| for (bt = block->buttons.first; bt; bt = bt->next) { | LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { | ||||
| if (block->flag & UI_BLOCK_CLIPBOTTOM) { | if (block->flag & UI_BLOCK_CLIPBOTTOM) { | ||||
| if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) { | if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) { | ||||
| bt->flag |= UI_SCROLLED; | bt->flag |= UI_SCROLLED; | ||||
| } | } | ||||
| } | } | ||||
| if (block->flag & UI_BLOCK_CLIPTOP) { | if (block->flag & UI_BLOCK_CLIPTOP) { | ||||
| if (bt->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) { | if (bt->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) { | ||||
| bt->flag |= UI_SCROLLED; | bt->flag |= UI_SCROLLED; | ||||
| Show All 10 Lines | static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle) | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| wmWindow *win = ctx_win; | wmWindow *win = ctx_win; | ||||
| bScreen *screen = CTX_wm_screen(C); | bScreen *screen = CTX_wm_screen(C); | ||||
| /* There may actually be a different window active than the one showing the popup, so lookup real | /* There may actually be a different window active than the one showing the popup, so lookup real | ||||
| * one. */ | * one. */ | ||||
| if (BLI_findindex(&screen->regionbase, handle->region) == -1) { | if (BLI_findindex(&screen->regionbase, handle->region) == -1) { | ||||
| for (win = wm->windows.first; win; win = win->next) { | LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) { | ||||
| screen = WM_window_get_active_screen(win); | screen = WM_window_get_active_screen(win_iter); | ||||
| if (BLI_findindex(&screen->regionbase, handle->region) != -1) { | if (BLI_findindex(&screen->regionbase, handle->region) != -1) { | ||||
| win = win_iter; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(win && screen); | BLI_assert(win && screen); | ||||
| CTX_wm_window_set(C, win); | CTX_wm_window_set(C, win); | ||||
| ▲ Show 20 Lines • Show All 319 Lines • Show Last 20 Lines | |||||