diff options
author | George Vogiatzis <Gvgeo> | 2019-04-05 14:48:26 +0300 |
---|---|---|
committer | Jacques Lucke <mail@jlucke.com> | 2019-04-05 14:48:26 +0300 |
commit | a180b754eb40637a5d37eeb0ae60066f5a6f93d8 (patch) | |
tree | 3871e253a8f3b861b27dfd3f666535adffc606b0 /source/blender/editors/screen | |
parent | fce469a30c5075216671f9ce3738ed401ad9c03f (diff) |
Interface: New region type 'Footer', used by text editor
* It can be hidden by dragging it up/down.
* It can be at the top or bottom, independent of the header.
* It uses the color theme from the header.
* It does not change its color, when the area becomes active.
Currently, it is used in the text editor to display the file path.
Differential Revision: https://developer.blender.org/D4601
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/area.c | 60 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 9 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 108 |
3 files changed, 160 insertions, 17 deletions
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 886f2781312..0150127d6fb 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1111,15 +1111,9 @@ bool ED_region_is_overlap(int spacetype, int regiontype) } } else if (ELEM(spacetype, SPACE_VIEW3D, SPACE_IMAGE)) { - if (ELEM(regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS)) { + if (ELEM(regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) { return true; } - - if (ELEM(spacetype, SPACE_VIEW3D, SPACE_IMAGE)) { - if (regiontype == RGN_TYPE_HEADER) { - return true; - } - } } } @@ -1167,6 +1161,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, rct else if (ar->regiontype == RGN_TYPE_HEADER) { prefsizey = ED_area_headersize(); } + else if (ar->regiontype == RGN_TYPE_FOOTER) { + prefsizey = ED_area_footersize(); + } else if (ED_area_is_global(sa)) { prefsizey = ED_region_global_size_y(); } @@ -1520,6 +1517,11 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ARegion *ar, L wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Header", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } + if (flag & ED_KEYMAP_FOOTER) { + /* standard keymap for footer regions */ + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Footer", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } /* Keep last because of LMB/RMB handling, see: T57527. */ if (flag & ED_KEYMAP_GPENCIL) { @@ -1910,10 +1912,25 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi /* Sync header alignment. */ if (sync_header_alignment) { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_HEADER) { - ar->alignment = header_alignment; - break; + /* Spaces with footer. */ + if (st->spaceid == SPACE_TEXT){ + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_HEADER) { + ar->alignment = header_alignment; + } + if (ar->regiontype == RGN_TYPE_FOOTER) { + int footer_alignment = (header_alignment == RGN_ALIGN_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM; + ar->alignment = footer_alignment; + break; + } + } + } + else { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_HEADER) { + ar->alignment = header_alignment; + break; + } } } } @@ -2538,6 +2555,27 @@ int ED_area_header_alignment(const ScrArea *area) area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP); } +int ED_area_footersize(void) +{ + return ED_area_headersize(); +} + +int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback) +{ + for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_FOOTER) { + return ar->alignment; + } + } + return fallback; +} + +int ED_area_footer_alignment(const ScrArea *area) +{ + return ED_area_footer_alignment_or_fallback( + area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM); +} + /** * \return the final height of a global \a area, accounting for DPI. */ diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index cd5b557f986..41ce5455c3b 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -421,7 +421,11 @@ static void screen_refresh_headersizes(void) SpaceType *st; for (st = lb->first; st; st = st->next) { - ARegionType *art = BKE_regiontype_from_id(st, RGN_TYPE_HEADER); + ARegionType *art; + art = BKE_regiontype_from_id(st, RGN_TYPE_HEADER); + if (art) art->prefsizey = ED_area_headersize(); + + art = BKE_regiontype_from_id(st, RGN_TYPE_FOOTER); if (art) art->prefsizey = ED_area_headersize(); } } @@ -1259,7 +1263,8 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s for (ar = newa->regionbase.first; ar; ar = ar->next) { ar->flagfullscreen = ar->flag; - if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_HEADER, RGN_TYPE_TOOLS, RGN_TYPE_NAV_BAR, RGN_TYPE_EXECUTE)) { + if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_HEADER, RGN_TYPE_FOOTER, + RGN_TYPE_TOOLS, RGN_TYPE_NAV_BAR, RGN_TYPE_EXECUTE)) { ar->flag |= RGN_FLAG_HIDDEN; } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index ed96621a906..09ca0476b10 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2317,12 +2317,13 @@ static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge) dist -= ar->winx; } else if (scalear->alignment == RGN_ALIGN_TOP && - (ar->alignment == RGN_ALIGN_BOTTOM || ar->regiontype == RGN_TYPE_HEADER)) + (ar->alignment == RGN_ALIGN_BOTTOM || ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_FOOTER))) { dist -= ar->winy; } else if (scalear->alignment == RGN_ALIGN_BOTTOM && - (ar->alignment == RGN_ALIGN_TOP || ar->regiontype == RGN_TYPE_HEADER)) { + (ar->alignment == RGN_ALIGN_TOP || ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_FOOTER))) + { dist -= ar->winy; } } @@ -2469,8 +2470,8 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) } CLAMP(rmd->ar->sizey, 0, rmd->maxsize); - /* note, 'UI_UNIT_Y/4' means you need to drag the header almost - * all the way down for it to become hidden, this is done + /* note, 'UI_UNIT_Y/4' means you need to drag the footer and execute region + * almost all the way down for it to become hidden, this is done * otherwise its too easy to do this by accident */ if (rmd->ar->sizey < UI_UNIT_Y / 4) { rmd->ar->sizey = rmd->origval; @@ -3850,6 +3851,103 @@ static void SCREEN_OT_header_context_menu(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Footer Toggle Operator + * \{ */ + +static int footer_exec(bContext *C, wmOperator *UNUSED(op)) +{ + ARegion *ar = screen_find_region_type(C, RGN_TYPE_FOOTER); + + if (ar == NULL) { + return OPERATOR_CANCELLED; + } + + ar->flag ^= RGN_FLAG_HIDDEN; + + ED_area_tag_redraw(CTX_wm_area(C)); + + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +static void SCREEN_OT_footer(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Toggle Footer"; + ot->description = "Toggle footer display"; + ot->idname = "SCREEN_OT_footer"; + + /* api callbacks */ + ot->exec = footer_exec; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Footer Tools Operator + * \{ */ + +static bool footer_context_menu_poll(bContext *C) +{ + ScrArea *sa = CTX_wm_area(C); + return sa; +} + +void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg)) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") : IFACE_("Flip to Top"); + + uiItemO(layout, IFACE_("Toggle Footer"), ICON_NONE, "SCREEN_OT_footer"); + + /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ + uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); + + uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); + + + /* file browser should be fullscreen all the time, topbar should + * never be. But other regions can be maximized/restored... */ + if (!ELEM(sa->spacetype, SPACE_FILE, SPACE_TOPBAR)) { + uiItemS(layout); + + const char *but_str = sa->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); + uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); + } +} + +static int footer_context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) +{ + uiPopupMenu *pup; + uiLayout *layout; + + pup = UI_popup_menu_begin(C, IFACE_("Footer"), ICON_NONE); + layout = UI_popup_menu_layout(pup); + + ED_screens_footer_tools_menu_create(C, layout, NULL); + + UI_popup_menu_end(C, pup); + + return OPERATOR_INTERFACE; +} + +static void SCREEN_OT_footer_context_menu(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Footer Context Menu"; + ot->description = "Display footer region context menu"; + ot->idname = "SCREEN_OT_footer_context_menu"; + + /* api callbacks */ + ot->poll = footer_context_menu_poll; + ot->invoke = footer_context_menu_invoke; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Navigation Bar Tools Menu * \{ */ @@ -4968,6 +5066,8 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_header); WM_operatortype_append(SCREEN_OT_header_toggle_menus); WM_operatortype_append(SCREEN_OT_header_context_menu); + WM_operatortype_append(SCREEN_OT_footer); + WM_operatortype_append(SCREEN_OT_footer_context_menu); WM_operatortype_append(SCREEN_OT_screen_set); WM_operatortype_append(SCREEN_OT_screen_full_area); WM_operatortype_append(SCREEN_OT_back_to_previous); |