Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/screen/area.c
| Show First 20 Lines • Show All 296 Lines • ▼ Show 20 Lines | |||||
| static void area_azone_tag_update(ScrArea *area) | static void area_azone_tag_update(ScrArea *area) | ||||
| { | { | ||||
| area->flag |= AREA_FLAG_ACTIONZONES_UPDATE; | area->flag |= AREA_FLAG_ACTIONZONES_UPDATE; | ||||
| } | } | ||||
| static void region_draw_azones(ScrArea *area, ARegion *region) | static void region_draw_azones(ScrArea *area, ARegion *region) | ||||
| { | { | ||||
| AZone *az; | |||||
| if (!area) { | if (!area) { | ||||
| return; | return; | ||||
| } | } | ||||
| GPU_line_width(1.0f); | GPU_line_width(1.0f); | ||||
| GPU_blend(GPU_BLEND_ALPHA); | GPU_blend(GPU_BLEND_ALPHA); | ||||
| GPU_matrix_push(); | GPU_matrix_push(); | ||||
| GPU_matrix_translate_2f(-region->winrct.xmin, -region->winrct.ymin); | GPU_matrix_translate_2f(-region->winrct.xmin, -region->winrct.ymin); | ||||
| for (az = area->actionzones.first; az; az = az->next) { | LISTBASE_FOREACH (AZone *, az, &area->actionzones) { | ||||
| /* test if action zone is over this region */ | /* test if action zone is over this region */ | ||||
| rcti azrct; | rcti azrct; | ||||
| BLI_rcti_init(&azrct, az->x1, az->x2, az->y1, az->y2); | BLI_rcti_init(&azrct, az->x1, az->x2, az->y1, az->y2); | ||||
| if (BLI_rcti_isect(®ion->drawrct, &azrct, NULL)) { | if (BLI_rcti_isect(®ion->drawrct, &azrct, NULL)) { | ||||
| if (az->type == AZONE_AREA) { | if (az->type == AZONE_AREA) { | ||||
| area_draw_azone(az->x1, az->y1, az->x2, az->y2); | area_draw_azone(az->x1, az->y1, az->x2, az->y2); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 374 Lines • ▼ Show 20 Lines | else { | ||||
| region->do_draw |= RGN_DRAW_NO_REBUILD; | region->do_draw |= RGN_DRAW_NO_REBUILD; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void ED_area_tag_redraw(ScrArea *area) | void ED_area_tag_redraw(ScrArea *area) | ||||
| { | { | ||||
| ARegion *region; | |||||
| if (area) { | if (area) { | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void ED_area_tag_redraw_no_rebuild(ScrArea *area) | void ED_area_tag_redraw_no_rebuild(ScrArea *area) | ||||
| { | { | ||||
| ARegion *region; | |||||
| if (area) { | if (area) { | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| ED_region_tag_redraw_no_rebuild(region); | ED_region_tag_redraw_no_rebuild(region); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void ED_area_tag_redraw_regiontype(ScrArea *area, int regiontype) | void ED_area_tag_redraw_regiontype(ScrArea *area, int regiontype) | ||||
| { | { | ||||
| ARegion *region; | |||||
| if (area) { | if (area) { | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| if (region->regiontype == regiontype) { | if (region->regiontype == regiontype) { | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void ED_area_tag_refresh(ScrArea *area) | void ED_area_tag_refresh(ScrArea *area) | ||||
| { | { | ||||
| if (area) { | if (area) { | ||||
| area->do_refresh = true; | area->do_refresh = true; | ||||
| } | } | ||||
| } | } | ||||
| /* *************************************************************** */ | /* *************************************************************** */ | ||||
| /* use NULL to disable it */ | /* use NULL to disable it */ | ||||
| void ED_area_status_text(ScrArea *area, const char *str) | void ED_area_status_text(ScrArea *area, const char *str) | ||||
| { | { | ||||
| ARegion *region; | |||||
| /* happens when running transform operators in background mode */ | /* happens when running transform operators in background mode */ | ||||
| if (area == NULL) { | if (area == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| if (region->regiontype == RGN_TYPE_HEADER) { | if (region->regiontype == RGN_TYPE_HEADER) { | ||||
| if (str) { | if (str) { | ||||
| if (region->headerstr == NULL) { | if (region->headerstr == NULL) { | ||||
| region->headerstr = MEM_mallocN(UI_MAX_DRAW_STR, "headerprint"); | region->headerstr = MEM_mallocN(UI_MAX_DRAW_STR, "headerprint"); | ||||
| } | } | ||||
| BLI_strncpy(region->headerstr, str, UI_MAX_DRAW_STR); | BLI_strncpy(region->headerstr, str, UI_MAX_DRAW_STR); | ||||
| BLI_str_rstrip(region->headerstr); | BLI_str_rstrip(region->headerstr); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 168 Lines • ▼ Show 20 Lines | case AE_RIGHT_TO_TOPLEFT: | ||||
| break; | break; | ||||
| } | } | ||||
| BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); | BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); | ||||
| } | } | ||||
| /* region already made zero sized, in shape of edge */ | /* region already made zero sized, in shape of edge */ | ||||
| static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region) | static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region) | ||||
| { | { | ||||
| AZone *azt; | |||||
| int tot = 0, add; | int tot = 0, add; | ||||
| /* Edge offset multiplied by the */ | /* Edge offset multiplied by the */ | ||||
| float edge_offset = 1.0f; | float edge_offset = 1.0f; | ||||
| const float tab_size_x = 0.7f * U.widget_unit; | const float tab_size_x = 0.7f * U.widget_unit; | ||||
| const float tab_size_y = 0.4f * U.widget_unit; | const float tab_size_y = 0.4f * U.widget_unit; | ||||
| for (azt = area->actionzones.first; azt; azt = azt->next) { | LISTBASE_FOREACH (AZone *, azt, &area->actionzones) { | ||||
| if (azt->edge == az->edge) { | if (azt->edge == az->edge) { | ||||
| tot++; | tot++; | ||||
| } | } | ||||
| } | } | ||||
| switch (az->edge) { | switch (az->edge) { | ||||
| case AE_TOP_TO_BOTTOMRIGHT: | case AE_TOP_TO_BOTTOMRIGHT: | ||||
| add = (region->winrct.ymax == area->totrct.ymin) ? 1 : 0; | add = (region->winrct.ymax == area->totrct.ymin) ? 1 : 0; | ||||
| ▲ Show 20 Lines • Show All 879 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* called in screen_refresh, or screens_init, also area size changes */ | /* called in screen_refresh, or screens_init, also area size changes */ | ||||
| void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) | void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) | ||||
| { | { | ||||
| WorkSpace *workspace = WM_window_get_active_workspace(win); | WorkSpace *workspace = WM_window_get_active_workspace(win); | ||||
| const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); | const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); | ||||
| ViewLayer *view_layer = WM_window_get_active_view_layer(win); | ViewLayer *view_layer = WM_window_get_active_view_layer(win); | ||||
| ARegion *region; | |||||
| rcti rect, overlap_rect; | rcti rect, overlap_rect; | ||||
| rcti window_rect; | rcti window_rect; | ||||
| if (ED_area_is_global(area) && (area->global->flag & GLOBAL_AREA_IS_HIDDEN)) { | if (ED_area_is_global(area) && (area->global->flag & GLOBAL_AREA_IS_HIDDEN)) { | ||||
| return; | return; | ||||
| } | } | ||||
| WM_window_rect_calc(win, &window_rect); | WM_window_rect_calc(win, &window_rect); | ||||
| /* set typedefinitions */ | /* set typedefinitions */ | ||||
| area->type = BKE_spacetype_from_id(area->spacetype); | area->type = BKE_spacetype_from_id(area->spacetype); | ||||
| if (area->type == NULL) { | if (area->type == NULL) { | ||||
| area->spacetype = SPACE_VIEW3D; | area->spacetype = SPACE_VIEW3D; | ||||
| area->type = BKE_spacetype_from_id(area->spacetype); | area->type = BKE_spacetype_from_id(area->spacetype); | ||||
| } | } | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| region->type = BKE_regiontype_from_id_or_first(area->type, region->regiontype); | region->type = BKE_regiontype_from_id_or_first(area->type, region->regiontype); | ||||
| } | } | ||||
| /* area sizes */ | /* area sizes */ | ||||
| area_calc_totrct(area, &window_rect); | area_calc_totrct(area, &window_rect); | ||||
| /* region rect sizes */ | /* region rect sizes */ | ||||
| rect = area->totrct; | rect = area->totrct; | ||||
| overlap_rect = rect; | overlap_rect = rect; | ||||
| region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0); | region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0); | ||||
| area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; | area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; | ||||
| /* default area handlers */ | /* default area handlers */ | ||||
| ed_default_handlers(wm, area, NULL, &area->handlers, area->type->keymapflag); | ed_default_handlers(wm, area, NULL, &area->handlers, area->type->keymapflag); | ||||
| /* checks spacedata, adds own handlers */ | /* checks spacedata, adds own handlers */ | ||||
| if (area->type->init) { | if (area->type->init) { | ||||
| area->type->init(wm, area); | area->type->init(wm, area); | ||||
| } | } | ||||
| /* clear all azones, add the area triangle widgets */ | /* clear all azones, add the area triangle widgets */ | ||||
| area_azone_init(win, screen, area); | area_azone_init(win, screen, area); | ||||
| /* region windows, default and own handlers */ | /* region windows, default and own handlers */ | ||||
| for (region = area->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| region_subwindow(region); | region_subwindow(region); | ||||
| if (region->visible) { | if (region->visible) { | ||||
| /* default region handlers */ | /* default region handlers */ | ||||
| ed_default_handlers(wm, area, region, ®ion->handlers, region->type->keymapflag); | ed_default_handlers(wm, area, region, ®ion->handlers, region->type->keymapflag); | ||||
| /* own handlers */ | /* own handlers */ | ||||
| if (region->type->init) { | if (region->type->init) { | ||||
| region->type->init(wm, region); | region->type->init(wm, region); | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /** | /** | ||||
| * we swap spaces for fullscreen to keep all allocated data area vertices were set | * we swap spaces for fullscreen to keep all allocated data area vertices were set | ||||
| */ | */ | ||||
| void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free) | void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free) | ||||
| { | { | ||||
| SpaceType *st; | SpaceType *st; | ||||
| ARegion *region; | |||||
| const char spacetype = area_dst->spacetype; | const char spacetype = area_dst->spacetype; | ||||
| const short flag_copy = HEADER_NO_PULLDOWN; | const short flag_copy = HEADER_NO_PULLDOWN; | ||||
| area_dst->spacetype = area_src->spacetype; | area_dst->spacetype = area_src->spacetype; | ||||
| area_dst->type = area_src->type; | area_dst->type = area_src->type; | ||||
| area_dst->flag = (area_dst->flag & ~flag_copy) | (area_src->flag & flag_copy); | area_dst->flag = (area_dst->flag & ~flag_copy) | (area_src->flag & flag_copy); | ||||
| /* area */ | /* area */ | ||||
| if (do_free) { | if (do_free) { | ||||
| BKE_spacedata_freelist(&area_dst->spacedata); | BKE_spacedata_freelist(&area_dst->spacedata); | ||||
| } | } | ||||
| BKE_spacedata_copylist(&area_dst->spacedata, &area_src->spacedata); | BKE_spacedata_copylist(&area_dst->spacedata, &area_src->spacedata); | ||||
| /* Note; SPACE_EMPTY is possible on new screens */ | /* Note; SPACE_EMPTY is possible on new screens */ | ||||
| /* regions */ | /* regions */ | ||||
| if (do_free) { | if (do_free) { | ||||
| st = BKE_spacetype_from_id(spacetype); | st = BKE_spacetype_from_id(spacetype); | ||||
| for (region = area_dst->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area_dst->regionbase) { | ||||
| BKE_area_region_free(st, region); | BKE_area_region_free(st, region); | ||||
| } | } | ||||
| BLI_freelistN(&area_dst->regionbase); | BLI_freelistN(&area_dst->regionbase); | ||||
| } | } | ||||
| st = BKE_spacetype_from_id(area_src->spacetype); | st = BKE_spacetype_from_id(area_src->spacetype); | ||||
| for (region = area_src->regionbase.first; region; region = region->next) { | LISTBASE_FOREACH (ARegion *, region, &area_src->regionbase) { | ||||
| ARegion *newar = BKE_area_region_copy(st, region); | ARegion *newar = BKE_area_region_copy(st, region); | ||||
| BLI_addtail(&area_dst->regionbase, newar); | BLI_addtail(&area_dst->regionbase, newar); | ||||
| } | } | ||||
| } | } | ||||
| void ED_area_data_swap(ScrArea *area_dst, ScrArea *area_src) | void ED_area_data_swap(ScrArea *area_dst, ScrArea *area_src) | ||||
| { | { | ||||
| SWAP(char, area_dst->spacetype, area_src->spacetype); | SWAP(char, area_dst->spacetype, area_src->spacetype); | ||||
| ▲ Show 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | |||||
| */ | */ | ||||
| void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_region_exit) | void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_region_exit) | ||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| if (area->spacetype != type) { | if (area->spacetype != type) { | ||||
| SpaceType *st; | SpaceType *st; | ||||
| SpaceLink *slold = area->spacedata.first; | SpaceLink *slold = area->spacedata.first; | ||||
| SpaceLink *sl; | |||||
| /* store area->type->exit callback */ | /* store area->type->exit callback */ | ||||
| void *area_exit = area->type ? area->type->exit : NULL; | void *area_exit = area->type ? area->type->exit : NULL; | ||||
| /* When the user switches between space-types from the type-selector, | /* When the user switches between space-types from the type-selector, | ||||
| * changing the header-type is jarring (especially when using Ctrl-MouseWheel). | * changing the header-type is jarring (especially when using Ctrl-MouseWheel). | ||||
| * | * | ||||
| * However, add-on install for example, forces the header to the top which shouldn't | * However, add-on install for example, forces the header to the top which shouldn't | ||||
| * be applied back to the previous space type when closing - see: T57724 | * be applied back to the previous space type when closing - see: T57724 | ||||
| * | * | ||||
| Show All 27 Lines | if (area->spacetype != type) { | ||||
| area->spacetype = type; | area->spacetype = type; | ||||
| area->type = st; | area->type = st; | ||||
| /* If st->create may be called, don't use context until then. The | /* If st->create may be called, don't use context until then. The | ||||
| * area->type->context() callback has changed but data may be invalid | * area->type->context() callback has changed but data may be invalid | ||||
| * (e.g. with properties editor) until space-data is properly created */ | * (e.g. with properties editor) until space-data is properly created */ | ||||
| /* check previously stored space */ | /* check previously stored space */ | ||||
| for (sl = area->spacedata.first; sl; sl = sl->next) { | SpaceLink *sl = NULL; | ||||
| if (sl->spacetype == type) { | LISTBASE_FOREACH (SpaceLink *, sl_iter, &area->spacedata) { | ||||
| if (sl_iter->spacetype == type) { | |||||
| sl = sl_iter; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* old spacedata... happened during work on 2.50, remove */ | /* old spacedata... happened during work on 2.50, remove */ | ||||
| if (sl && BLI_listbase_is_empty(&sl->regionbase)) { | if (sl && BLI_listbase_is_empty(&sl->regionbase)) { | ||||
| st->free(sl); | st->free(sl); | ||||
| BLI_freelinkN(&area->spacedata, sl); | BLI_freelinkN(&area->spacedata, sl); | ||||
| ▲ Show 20 Lines • Show All 332 Lines • ▼ Show 20 Lines | void ED_region_panels_layout_ex(const bContext *C, | ||||
| ARegion *region, | ARegion *region, | ||||
| ListBase *paneltypes, | ListBase *paneltypes, | ||||
| const char *contexts[], | const char *contexts[], | ||||
| const char *category_override) | const char *category_override) | ||||
| { | { | ||||
| /* collect panels to draw */ | /* collect panels to draw */ | ||||
| WorkSpace *workspace = CTX_wm_workspace(C); | WorkSpace *workspace = CTX_wm_workspace(C); | ||||
| LinkNode *panel_types_stack = NULL; | LinkNode *panel_types_stack = NULL; | ||||
| for (PanelType *pt = paneltypes->last; pt; pt = pt->prev) { | LISTBASE_FOREACH_BACKWARD (PanelType *, pt, paneltypes) { | ||||
| /* Only draw top level panels. */ | /* Only draw top level panels. */ | ||||
| if (pt->parent) { | if (pt->parent) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (category_override) { | if (category_override) { | ||||
| if (!STREQ(pt->category, category_override)) { | if (!STREQ(pt->category, category_override)) { | ||||
| continue; | continue; | ||||
| ▲ Show 20 Lines • Show All 260 Lines • ▼ Show 20 Lines | void ED_region_panels_init(wmWindowManager *wm, ARegion *region) | ||||
| WM_event_add_keymap_handler(®ion->handlers, keymap); | WM_event_add_keymap_handler(®ion->handlers, keymap); | ||||
| } | } | ||||
| void ED_region_header_layout(const bContext *C, ARegion *region) | void ED_region_header_layout(const bContext *C, ARegion *region) | ||||
| { | { | ||||
| const uiStyle *style = UI_style_get_dpi(); | const uiStyle *style = UI_style_get_dpi(); | ||||
| uiBlock *block; | uiBlock *block; | ||||
| uiLayout *layout; | uiLayout *layout; | ||||
| HeaderType *ht; | |||||
| Header header = {NULL}; | Header header = {NULL}; | ||||
| bool region_layout_based = region->flag & RGN_FLAG_DYNAMIC_SIZE; | bool region_layout_based = region->flag & RGN_FLAG_DYNAMIC_SIZE; | ||||
| /* Height of buttons and scaling needed to achieve it. */ | /* Height of buttons and scaling needed to achieve it. */ | ||||
| const int buttony = min_ii(UI_UNIT_Y, region->winy - 2 * UI_DPI_FAC); | const int buttony = min_ii(UI_UNIT_Y, region->winy - 2 * UI_DPI_FAC); | ||||
| const float buttony_scale = buttony / (float)UI_UNIT_Y; | const float buttony_scale = buttony / (float)UI_UNIT_Y; | ||||
| /* Vertically center buttons. */ | /* Vertically center buttons. */ | ||||
| int xco = UI_HEADER_OFFSET; | int xco = UI_HEADER_OFFSET; | ||||
| int yco = buttony + (region->winy - buttony) / 2; | int yco = buttony + (region->winy - buttony) / 2; | ||||
| int maxco = xco; | int maxco = xco; | ||||
| /* XXX workaround for 1 px alignment issue. Not sure what causes it... | /* XXX workaround for 1 px alignment issue. Not sure what causes it... | ||||
| * Would prefer a proper fix - Julian */ | * Would prefer a proper fix - Julian */ | ||||
| if (!ELEM(CTX_wm_area(C)->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR)) { | if (!ELEM(CTX_wm_area(C)->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR)) { | ||||
| yco -= 1; | yco -= 1; | ||||
| } | } | ||||
| /* set view2d view matrix for scrolling (without scrollers) */ | /* set view2d view matrix for scrolling (without scrollers) */ | ||||
| UI_view2d_view_ortho(®ion->v2d); | UI_view2d_view_ortho(®ion->v2d); | ||||
| /* draw all headers types */ | /* draw all headers types */ | ||||
| for (ht = region->type->headertypes.first; ht; ht = ht->next) { | LISTBASE_FOREACH (HeaderType *, ht, ®ion->type->headertypes) { | ||||
| if (ht->poll && !ht->poll(C, ht)) { | if (ht->poll && !ht->poll(C, ht)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| block = UI_block_begin(C, region, ht->idname, UI_EMBOSS); | block = UI_block_begin(C, region, ht->idname, UI_EMBOSS); | ||||
| layout = UI_block_layout( | layout = UI_block_layout( | ||||
| block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, buttony, 1, 0, style); | block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, buttony, 1, 0, style); | ||||
| ▲ Show 20 Lines • Show All 825 Lines • Show Last 20 Lines | |||||