diff options
25 files changed, 362 insertions, 116 deletions
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 3382633af60..d43792bc61d 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -1152,7 +1152,8 @@ class CLIP_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class CLIP_MT_clip(Menu): diff --git a/release/scripts/startup/bl_ui/space_console.py b/release/scripts/startup/bl_ui/space_console.py index ec16cfd89be..327fb94cb95 100644 --- a/release/scripts/startup/bl_ui/space_console.py +++ b/release/scripts/startup/bl_ui/space_console.py @@ -70,7 +70,8 @@ class CONSOLE_MT_console(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class CONSOLE_MT_language(Menu): diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index eeb08916416..79240bbf72a 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -186,7 +186,8 @@ class DOPESHEET_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class DOPESHEET_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index 3d39234ce08..6fc3d9e4f2b 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -118,7 +118,8 @@ class GRAPH_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class GRAPH_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 0b97a2dda28..bdb0ca7aa15 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -110,7 +110,8 @@ class IMAGE_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class IMAGE_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py index 9792a26d224..16182da1018 100644 --- a/release/scripts/startup/bl_ui/space_logic.py +++ b/release/scripts/startup/bl_ui/space_logic.py @@ -120,7 +120,8 @@ class LOGIC_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index 7634620cf0d..b748e904f31 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -89,7 +89,8 @@ class NLA_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class NLA_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 24e8d2e4a53..17eeeec2480 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -180,7 +180,8 @@ class NODE_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class NODE_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 01165bf2889..7b508c067e1 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -96,7 +96,8 @@ class OUTLINER_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class OUTLINER_MT_search(Menu): diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index ce00d4eb8e7..7b1b02271c5 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -198,7 +198,8 @@ class SEQUENCER_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class SEQUENCER_MT_select(Menu): diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index a430fb09165..5eb4e333130 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -181,7 +181,8 @@ class TEXT_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class TEXT_MT_text(Menu): diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index cfb147b3566..d23ee84d9d2 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -145,7 +145,8 @@ class TIME_MT_view(Menu): layout.separator() layout.operator("screen.area_dupli") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class TIME_MT_cache(Menu): diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index cbae63e1f9a..b5d29b5300c 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -421,7 +421,8 @@ class VIEW3D_MT_view(Menu): layout.operator("screen.area_dupli") layout.operator("screen.region_quadview") - layout.operator("screen.screen_full_area") + layout.operator("screen.screen_full_area", text="Toggle Maximize Area") + layout.operator("screen.screen_full_area").use_hide_panels = True class VIEW3D_MT_view_navigation(Menu): diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index d31be3e961f..ed2465647da 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -110,7 +110,7 @@ void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, in ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type); void ED_screen_full_prevspace(struct bContext *C, ScrArea *sa); void ED_screen_full_restore(struct bContext *C, ScrArea *sa); -struct ScrArea *ED_screen_full_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa); +struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa, const short state); void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg); /* anim */ diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index 2b02606c6d9..effecf43839 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -93,10 +93,13 @@ typedef struct AZone { short x1, y1, x2, y2; /* for clip */ rcti rect; + /* for fade in/out */ + float alpha; } AZone; /* actionzone type */ #define AZONE_AREA 1 /* corner widgets for splitting areas */ #define AZONE_REGION 2 /* when a region is collapsed, draw a handle to expose */ +#define AZONE_FULLSCREEN 3 /* when in editor fullscreen draw a corner to go to normal mode */ #endif /* __ED_SCREEN_TYPES_H__ */ diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c index 0beb5737ec7..ab28f5fa675 100644 --- a/source/blender/editors/render/render_view.c +++ b/source/blender/editors/render/render_view.c @@ -252,7 +252,7 @@ static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op)) } else if (sima->flag & SI_FULLWINDOW) { sima->flag &= ~SI_FULLWINDOW; - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 752f388c338..901ab67d6cd 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -63,6 +63,7 @@ #include "BLF_api.h" #include "UI_interface.h" +#include "UI_interface_icons.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -149,6 +150,45 @@ void ED_area_do_refresh(bContext *C, ScrArea *sa) } /** + * \brief Corner widget use for quitting fullscreen. + */ +static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, float alpha) +{ + int x = x2 - ((float) x2 - x1) * 0.5f / UI_DPI_FAC; + int y = y2 - ((float) y2 - y1) * 0.5f / UI_DPI_FAC; + + /* adjust the icon distance from the corner */ + x += 36.0f / UI_DPI_FAC; + y += 36.0f / UI_DPI_FAC; + + /* draws from the left bottom corner of the icon */ + x -= UI_DPI_ICON_SIZE; + y -= UI_DPI_ICON_SIZE; + + alpha = min_ff(alpha, 0.75f); + + UI_icon_draw_aspect(x, y, ICON_FULLSCREEN_EXIT, 0.7f / UI_DPI_FAC, alpha); + + /* debug drawing : + * The click_rect is the same as defined in fullscreen_click_rcti_init + * Keep them both in sync */ + + if (G.debug_value == 1) { + rcti click_rect; + float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; + char alpha_debug = 255 * alpha; + + BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size); + + glColor4ub(255, 0, 0, alpha_debug); + fdrawbox(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); + glColor4ub(0, 255, 255, alpha_debug); + fdrawline(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); + fdrawline(click_rect.xmin, click_rect.ymax, click_rect.xmax, click_rect.ymin); + } +} + +/** * \brief Corner widgets use for dragging and splitting the view. */ static void area_draw_azone(short x1, short y1, short x2, short y2) @@ -365,6 +405,9 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) } } } + else if (az->type == AZONE_FULLSCREEN) { + area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); + } } } @@ -567,10 +610,10 @@ static void area_azone_initialize(wmWindow *win, bScreen *screen, ScrArea *sa) { AZone *az; - /* reinitalize entirely, regions add azones too */ + /* reinitalize entirely, regions and fullscreen add azones too */ BLI_freelistN(&sa->actionzones); - if (screen->full != SCREENNORMAL) { + if (screen->state != SCREENNORMAL) { return; } @@ -602,6 +645,26 @@ static void area_azone_initialize(wmWindow *win, bScreen *screen, ScrArea *sa) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } +static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar) +{ + AZone *az; + + if (ar->regiontype != RGN_TYPE_WINDOW) + return; + + az = (AZone *)MEM_callocN(sizeof(AZone), "fullscreen action zone"); + BLI_addtail(&(sa->actionzones), az); + az->type = AZONE_FULLSCREEN; + az->ar = ar; + az->alpha = 0.0f; + + az->x1 = ar->winrct.xmax - (AZONEFADEOUT - 1); + az->y1 = ar->winrct.ymax - (AZONEFADEOUT - 1); + az->x2 = ar->winrct.xmax; + az->y2 = ar->winrct.ymax; + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); +} + #define AZONEPAD_EDGE (0.1f * U.widget_unit) #define AZONEPAD_ICON (0.45f * U.widget_unit) static void region_azone_edge(AZone *az, ARegion *ar) @@ -830,25 +893,30 @@ static void region_azone_tria(ScrArea *sa, AZone *az, ARegion *ar) } -static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge) +static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const bool is_fullscreen) { AZone *az; + const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) == 0; - az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); - BLI_addtail(&(sa->actionzones), az); - az->type = AZONE_REGION; - az->ar = ar; - az->edge = edge; + if (is_hidden || !is_fullscreen) { + az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); + BLI_addtail(&(sa->actionzones), az); + az->type = AZONE_REGION; + az->ar = ar; + az->edge = edge; + } if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { - if (G.debug_value == 3) - region_azone_icon(sa, az, ar); - else if (G.debug_value == 2) - region_azone_tria(sa, az, ar); - else if (G.debug_value == 1) - region_azone_tab(sa, az, ar); - else - region_azone_tab_plus(sa, az, ar); + if (!is_fullscreen) { + if (G.debug_value == 3) + region_azone_icon(sa, az, ar); + else if (G.debug_value == 2) + region_azone_tria(sa, az, ar); + else if (G.debug_value == 1) + region_azone_tab(sa, az, ar); + else + region_azone_tab_plus(sa, az, ar); + } } else { region_azone_edge(az, ar); @@ -859,18 +927,18 @@ static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge) /* *************************************************************** */ -static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment) +static void region_azone_add(ScrArea *sa, ARegion *ar, const int alignment, const bool is_fullscreen) { /* edge code (t b l r) is along which area edge azone will be drawn */ if (alignment == RGN_ALIGN_TOP) - region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT); + region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); else if (alignment == RGN_ALIGN_BOTTOM) - region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT); + region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); else if (alignment == RGN_ALIGN_RIGHT) - region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT); + region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT, is_fullscreen); else if (alignment == RGN_ALIGN_LEFT) - region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT); + region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT, is_fullscreen); } /* dir is direction to check, not the splitting edge direction! */ @@ -1188,7 +1256,13 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti * must be minimum '4' */ } else { - region_azone_add(sa, ar, alignment); + if (ELEM(win->screen->state, SCREENNORMAL, SCREENMAXIMIZED)) { + region_azone_add(sa, ar, alignment, false); + } + else { + region_azone_add(sa, ar, alignment, true); + fullscreen_azone_initialize(sa, ar); + } } region_rect_recursive(win, sa, ar->next, remainder, quad); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 12236e3779d..e9aa3ffdcd5 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1058,7 +1058,7 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc) { bScreen *newsc; - if (sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */ + if (sc->state != SCREENNORMAL) return NULL; /* XXX handle this case! */ /* make new empty screen: */ newsc = ED_screen_add(win, sc->scene, sc->id.name + 2); @@ -1485,7 +1485,7 @@ void ED_screen_set(bContext *C, bScreen *sc) return; - if (sc->full) { /* find associated full */ + if (sc->state == SCREENFULL) { /* find associated full */ bScreen *sc1; for (sc1 = bmain->screen.first; sc1; sc1 = sc1->id.next) { ScrArea *sa = sc1->areabase.first; @@ -1586,7 +1586,7 @@ void ED_screen_delete(bContext *C, bScreen *sc) int delete = 1; /* don't allow deleting temp fullscreens for now */ - if (sc->full == SCREENFULL) { + if (ELEM(sc->state, SCREENMAXIMIZED, SCREENFULL)) { return; } @@ -1730,11 +1730,11 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) ScrArea *newsa = NULL; if (!sa || sa->full == NULL) { - newsa = ED_screen_full_toggle(C, win, sa); + newsa = ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } if (!newsa) { - if (sa->full) { + if (sa->full && (screen->state == SCREENMAXIMIZED)) { /* if this has been called from the temporary info header generated in * temp fullscreen layouts, find the correct fullscreen area to change * to create a new space inside */ @@ -1760,7 +1760,7 @@ void ED_screen_full_prevspace(bContext *C, ScrArea *sa) ED_area_prevspace(C, sa); if (sa->full) - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* restore a screen / area back to default operation, after temp fullscreen modes */ @@ -1768,6 +1768,8 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) { wmWindow *win = CTX_wm_window(C); SpaceLink *sl = sa->spacedata.first; + bScreen *screen = CTX_wm_screen(C); + short state = (screen ? screen->state : SCREENMAXIMIZED); /* if fullscreen area has a secondary space (such as a file browser or fullscreen render * overlaid on top of a existing setup) then return to the previous space */ @@ -1785,23 +1787,23 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) ED_screen_full_prevspace(C, sa); } else - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, state); } else if (sl->spacetype == SPACE_FILE) { ED_screen_full_prevspace(C, sa); } else { - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, state); } } /* otherwise just tile the area again */ else { - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, state); } } -/* this function toggles: if area is full then the parent will be restored */ -ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) +/* this function toggles: if area is maximized/full then the parent will be restored */ +ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const short state) { bScreen *sc, *oldscreen; ARegion *ar; @@ -1812,23 +1814,20 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) * are no longer in the same screen */ for (ar = sa->regionbase.first; ar; ar = ar->next) uiFreeBlocks(C, &ar->uiblocks); - + /* prevent hanging header prints */ ED_area_headerprint(sa, NULL); } if (sa && sa->full) { + /* restoring back to SCREENNORMAL */ ScrArea *old; - /*short fulltype;*/ /*UNUSED*/ sc = sa->full; /* the old screen to restore */ oldscreen = win->screen; /* the one disappearing */ - /*fulltype = sc->full;*/ - sc->full = 0; + sc->state = SCREENNORMAL; - /* removed: SCREENAUTOPLAY exception here */ - /* find old area */ for (old = sc->areabase.first; old; old = old->next) if (old->full) break; @@ -1838,6 +1837,13 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) return NULL; } + if (state == SCREENFULL) { + /* restore the old side panels/header visibility */ + for (ar = sa->regionbase.first; ar; ar = ar->next) { + ar->flag = ar->flagfullscreen; + } + } + ED_area_data_swap(old, sa); if (sa->flag & AREA_TEMP_INFO) sa->flag &= ~AREA_TEMP_INFO; old->full = NULL; @@ -1853,44 +1859,67 @@ ScrArea *ED_screen_full_toggle(bContext *C, wmWindow *win, ScrArea *sa) } else { + /* change from SCREENNORMAL to new state */ ScrArea *newa; char newname[MAX_ID_NAME - 2]; oldscreen = win->screen; - /* nothing wrong with having only 1 area, as far as I can see... - * is there only 1 area? */ -#if 0 - if (oldscreen->areabase.first == oldscreen->areabase.last) - return NULL; -#endif - - oldscreen->full = SCREENFULL; - BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "full"); + oldscreen->state = state; + BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal"); sc = ED_screen_add(win, oldscreen->scene, newname); - sc->full = SCREENFULL; // XXX + sc->state = state; /* timer */ sc->animtimer = oldscreen->animtimer; oldscreen->animtimer = NULL; - /* returns the top small area */ - newa = area_split(sc, (ScrArea *)sc->areabase.first, 'h', 0.99f, 1); - ED_area_newspace(C, newa, SPACE_INFO); - /* use random area when we have no active one, e.g. when the * mouse is outside of the window and we open a file browser */ if (!sa) sa = oldscreen->areabase.first; - /* copy area */ - newa = newa->prev; - ED_area_data_swap(newa, sa); - sa->flag |= AREA_TEMP_INFO; + if (state == SCREENMAXIMIZED) { + /* returns the top small area */ + newa = area_split(sc, (ScrArea *)sc->areabase.first, 'h', 0.99f, 1); + ED_area_newspace(C, newa, SPACE_INFO); + + /* copy area */ + newa = newa->prev; + ED_area_data_swap(newa, sa); + sa->flag |= AREA_TEMP_INFO; + + sa->full = oldscreen; + newa->full = oldscreen; + newa->next->full = oldscreen; // XXX + } + else if (state == SCREENFULL) { + newa = (ScrArea *)sc->areabase.first; + + /* copy area */ + ED_area_data_swap(newa, sa); + newa->flag = sa->flag; /* mostly for AREA_FLAG_WASFULLSCREEN */ + + /* temporarily hide the side panels/header */ + for (ar = newa->regionbase.first; ar; ar = ar->next) { + ar->flagfullscreen = ar->flag; + + if (ELEM(ar->regiontype, + RGN_TYPE_UI, + RGN_TYPE_PREVIEW, + RGN_TYPE_HEADER, + RGN_TYPE_TOOLS)) + { + ar->flag |= RGN_FLAG_HIDDEN; + } + } - sa->full = oldscreen; - newa->full = oldscreen; - newa->next->full = oldscreen; // XXX + sa->full = oldscreen; + newa->full = oldscreen; + } + else { + BLI_assert(false); + } ED_screen_set(C, sc); } diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 9e0421b6e99..79036d3356f 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -36,6 +36,8 @@ struct wmWindow; struct Scene; #define AZONESPOT (0.6f * U.widget_unit) +#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */ +#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */ /* area.c */ void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7c7574b3af3..8be25e34f6f 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -129,13 +129,31 @@ static int screen_active_editable(bContext *C) { if (ED_operator_screenactive(C)) { /* no full window splitting allowed */ - if (CTX_wm_screen(C)->full != SCREENNORMAL) + if (CTX_wm_screen(C)->state != SCREENNORMAL) return 0; return 1; } return 0; } +static ARegion *screen_find_region_type(bContext *C, int type) +{ + ARegion *ar = CTX_wm_region(C); + + /* find the header region + * - try context first, but upon failing, search all regions in area... + */ + if ((ar == NULL) || (ar->regiontype != type)) { + ScrArea *sa = CTX_wm_area(C); + ar = BKE_area_find_region_type(sa, type); + } + else { + ar = NULL; + } + + return ar; +} + /* when mouse is over area-edge */ int ED_operator_screen_mainwinactive(bContext *C) { @@ -611,6 +629,24 @@ static int actionzone_area_poll(bContext *C) return 0; } +/* the debug drawing of the click_rect is in area_draw_azone_fullscreen, keep both in sync */ +static void fullscreen_click_rcti_init(rcti *rect, const short x1, const short y1, const short x2, const short y2) +{ + int x = x2 - ((float) x2 - x1) * 0.5f / UI_DPI_FAC; + int y = y2 - ((float) y2 - y1) * 0.5f / UI_DPI_FAC; + float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; + + /* adjust the icon distance from the corner */ + x += 36.0f / UI_DPI_FAC; + y += 36.0f / UI_DPI_FAC; + + /* draws from the left bottom corner of the icon */ + x -= UI_DPI_ICON_SIZE; + y -= UI_DPI_ICON_SIZE; + + BLI_rcti_init(rect, x, x + icon_size, y, y + icon_size); +} + AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]) { AZone *az = NULL; @@ -627,6 +663,42 @@ AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]) else if (az->type == AZONE_REGION) { break; } + else if (az->type == AZONE_FULLSCREEN) { + int mouse_radius, spot_radius, fadein_radius, fadeout_radius; + rcti click_rect; + + fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2); + + if (BLI_rcti_isect_pt_v(&click_rect, xy)) { + az->alpha = 1.0f; + } + else { + mouse_radius = (xy[0] - az->x2) * (xy[0] - az->x2) + (xy[1] - az->y2) * (xy[1] - az->y2); + spot_radius = AZONESPOT * AZONESPOT; + fadein_radius = AZONEFADEIN * AZONEFADEIN; + fadeout_radius = AZONEFADEOUT * AZONEFADEOUT; + + if (mouse_radius < spot_radius) { + az->alpha = 1.0f; + } + else if (mouse_radius < fadein_radius) { + az->alpha = 1.0f; + } + else if (mouse_radius < fadeout_radius) { + az->alpha = 1.0f - ((float)(mouse_radius - fadein_radius)) / ((float)(fadeout_radius - fadein_radius)); + } + else { + az->alpha = 0.0f; + } + + /* fade in/out but no click */ + az = NULL; + } + + /* XXX force redraw to show/hide the action zone */ + ED_area_tag_redraw(sa); + break; + } } } @@ -654,8 +726,11 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type) if (type == AZONE_AREA) event.type = EVT_ACTIONZONE_AREA; + else if (type == AZONE_FULLSCREEN) + event.type = EVT_ACTIONZONE_FULLSCREEN; else event.type = EVT_ACTIONZONE_REGION; + event.val = 0; event.customdata = op->customdata; event.customdatafree = true; @@ -680,8 +755,8 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event) sad->x = event->x; sad->y = event->y; /* region azone directly reacts on mouse clicks */ - if (sad->az->type == AZONE_REGION) { - actionzone_apply(C, op, AZONE_REGION); + if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) { + actionzone_apply(C, op, sad->az->type); actionzone_exit(op); return OPERATOR_FINISHED; } @@ -1462,7 +1537,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) int dir; /* no full window splitting allowed */ - if (sc->full != SCREENNORMAL) + if (sc->state != SCREENNORMAL) return OPERATOR_CANCELLED; if (event->type == EVT_ACTIONZONE_AREA) { @@ -2231,8 +2306,8 @@ static void SCREEN_OT_marker_jump(wmOperatorType *ot) static bool screen_set_is_ok(bScreen *screen, bScreen *screen_prev) { - return ((screen->winid == 0) && - (screen->full == 0) && + return ((screen->winid == 0) && + (screen->state == SCREENNORMAL) && (screen != screen_prev) && (screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT))); } @@ -2303,10 +2378,11 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot) /* function to be called outside UI context, or for redo */ -static int screen_full_area_exec(bContext *C, wmOperator *UNUSED(op)) +static int screen_maximize_area_exec(bContext *C, wmOperator *op) { bScreen *screen = CTX_wm_screen(C); ScrArea *sa = NULL; + const bool hide_panels = RNA_boolean_get(op->ptr, "use_hide_panels"); /* search current screen for 'fullscreen' areas */ /* prevents restoring info header, when mouse is over it */ @@ -2314,25 +2390,41 @@ static int screen_full_area_exec(bContext *C, wmOperator *UNUSED(op)) if (sa->full) break; } - if (sa == NULL) sa = CTX_wm_area(C); + if (sa == NULL) { + sa = CTX_wm_area(C); + } - ED_screen_full_toggle(C, CTX_wm_window(C), sa); + if (hide_panels) { + if (!ELEM(screen->state, SCREENNORMAL, SCREENFULL)) { + return OPERATOR_CANCELLED; + } + ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENFULL); + } + else { + if (!ELEM(screen->state, SCREENNORMAL, SCREENMAXIMIZED)) { + return OPERATOR_CANCELLED; + } + ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED); + } + return OPERATOR_FINISHED; } static void SCREEN_OT_screen_full_area(wmOperatorType *ot) { - ot->name = "Toggle Full Screen"; - ot->description = "Toggle display selected area as fullscreen"; + PropertyRNA *prop; + + ot->name = "Toggle Fullscreen Area"; + ot->description = "Toggle display selected area as fullscreen/maximized"; ot->idname = "SCREEN_OT_screen_full_area"; - ot->exec = screen_full_area_exec; + ot->exec = screen_maximize_area_exec; ot->poll = ED_operator_areaactive; ot->flag = 0; - -} - + prop = RNA_def_boolean(ot->srna, "use_hide_panels", false, "Hide Panels", "Hide all the panels"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} /* ************** join area operator ********************************************** */ @@ -3027,23 +3119,44 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot) ot->flag = 0; } +/* ************** header operator ***************************** */ +static int header_exec(bContext *C, wmOperator *UNUSED(op)) +{ + ARegion *ar = screen_find_region_type(C, RGN_TYPE_HEADER); + + 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_header(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Header"; + ot->description = "Display display header"; + ot->idname = "SCREEN_OT_header"; + + /* api callbacks */ + ot->exec = header_exec; +} + /* ************** header flip operator ***************************** */ /* flip a header region alignment */ static int header_flip_exec(bContext *C, wmOperator *UNUSED(op)) { - ARegion *ar = CTX_wm_region(C); - - /* find the header region - * - try context first, but upon failing, search all regions in area... - */ - if ((ar == NULL) || (ar->regiontype != RGN_TYPE_HEADER)) { - ScrArea *sa = CTX_wm_area(C); - ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + ARegion *ar = screen_find_region_type(C, RGN_TYPE_HEADER); - /* don't do anything if no region */ - if (ar == NULL) - return OPERATOR_CANCELLED; + if (ar == NULL) { + return OPERATOR_CANCELLED; } /* copied from SCREEN_OT_region_flip */ @@ -3945,6 +4058,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_region_scale); WM_operatortype_append(SCREEN_OT_region_flip); WM_operatortype_append(SCREEN_OT_header_flip); + WM_operatortype_append(SCREEN_OT_header); WM_operatortype_append(SCREEN_OT_header_toggle_menus); WM_operatortype_append(SCREEN_OT_header_toolbox); WM_operatortype_append(SCREEN_OT_screen_set); @@ -4047,6 +4161,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "SCREEN_OT_area_options", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_header", F9KEY, KM_PRESS, KM_ALT, 0); /* Header Editing ------------------------------------------------ */ keymap = WM_keymap_find(keyconf, "Header", 0, 0); @@ -4066,6 +4181,11 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", UPARROWKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", DOWNARROWKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_SHIFT, 0); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", F10KEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "use_hide_panels", true); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", EVT_ACTIONZONE_FULLSCREEN, 0, 0, 0); + RNA_boolean_set(kmi->ptr, "use_hide_panels", true); + WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 8a900c3946e..47a08c62f95 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -60,7 +60,7 @@ typedef struct bScreen { int redraws_flag; /* user-setting for which editors get redrawn during anim playback (used to be time->redraws) */ int pad1; - short full; /* temp screen for image render display or fileselect */ + short state; /* temp screen for image render display or fileselect */ short temp; /* temp screen in a temp window, don't save (like user prefs) */ short winid; /* winid from WM, starts with 1 */ short do_draw; /* notifier for drawing edges */ @@ -247,7 +247,8 @@ typedef struct ARegion { short do_draw_overlay; /* private, cached notifier events */ short swap; /* private, indicator to survive swap-exchange */ short overlap; /* private, set for indicate drawing overlapped */ - short pad[2]; + short flagfullscreen; /* temporary copy of flag settings for clean fullscreen */ + short pad; struct ARegionType *type; /* callbacks for this region type */ @@ -287,9 +288,12 @@ typedef struct ARegion { #define HEADERDOWN 1 #define HEADERTOP 2 -/* screen->full */ -#define SCREENNORMAL 0 -#define SCREENFULL 1 +/* screen->state */ +enum { + SCREENNORMAL = 0, + SCREENMAXIMIZED = 1, /* one editor taking over the screen */ + SCREENFULL = 2, /* one editor taking over the screen with no bare-minimum UI elements */ +}; /* Panel->flag */ enum { diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index cf591dc7750..86a28fb80bf 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -116,7 +116,7 @@ static int rna_Screen_is_animation_playing_get(PointerRNA *UNUSED(ptr)) static int rna_Screen_fullscreen_get(PointerRNA *ptr) { bScreen *sc = (bScreen *)ptr->data; - return (sc->full != 0); + return (sc->state == SCREENMAXIMIZED); } /* UI compatible list: should not be needed, but for now we need to keep EMPTY @@ -398,7 +398,7 @@ static void rna_def_screen(BlenderRNA *brna) prop = RNA_def_property(srna, "show_fullscreen", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_funcs(prop, "rna_Screen_fullscreen_get", NULL); - RNA_def_property_ui_text(prop, "Fullscreen", "An area is maximized, filling this screen"); + RNA_def_property_ui_text(prop, "Maximize", "An area is maximized, filling this screen"); /* Define Anim Playback Areas */ prop = RNA_def_property(srna, "use_play_top_left_3d_editor", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 139e0101859..f762e19c969 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -308,7 +308,7 @@ bool WM_init_game(bContext *C) /* full screen the area */ if (!sa->full) { - ED_screen_full_toggle(C, win, sa); + ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* Fullscreen */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 016446e0a63..68aad2dbda6 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2098,7 +2098,7 @@ static int wm_operator_winactive_normal(bContext *C) { wmWindow *win = CTX_wm_window(C); - if (win == NULL || win->screen == NULL || win->screen->full != SCREENNORMAL) + if (win == NULL || win->screen == NULL || win->screen->state != SCREENNORMAL) return 0; return 1; @@ -2946,7 +2946,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot) { - ot->name = "Toggle Fullscreen"; + ot->name = "Toggle Window Fullscreen"; ot->idname = "WM_OT_window_fullscreen_toggle"; ot->description = "Toggle the current window fullscreen"; diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index f50f98ed40c..7dfc2b52c33 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -299,13 +299,14 @@ enum { /* Tweak, gestures: 0x500x, 0x501x */ EVT_ACTIONZONE_AREA = 0x5000, EVT_ACTIONZONE_REGION = 0x5001, + EVT_ACTIONZONE_FULLSCREEN = 0x5002, /* tweak events, for L M R mousebuttons */ - EVT_TWEAK_L = 0x5002, - EVT_TWEAK_M = 0x5003, - EVT_TWEAK_R = 0x5004, + EVT_TWEAK_L = 0x5003, + EVT_TWEAK_M = 0x5004, + EVT_TWEAK_R = 0x5005, /* tweak events for action or select mousebutton */ - EVT_TWEAK_A = 0x5005, - EVT_TWEAK_S = 0x5006, + EVT_TWEAK_A = 0x5006, + EVT_TWEAK_S = 0x5007, EVT_GESTURE = 0x5010, /* Misc Blender internals: 0x502x */ |