diff options
Diffstat (limited to 'source/blender/editors/screen/screen_ops.c')
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 796 |
1 files changed, 497 insertions, 299 deletions
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 1f5b51d211c..d74a9ed288c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -39,6 +39,7 @@ #include "BLT_translation.h" +#include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_lattice_types.h" #include "DNA_object_types.h" @@ -48,11 +49,14 @@ #include "DNA_meta_types.h" #include "DNA_mask_types.h" #include "DNA_node_types.h" +#include "DNA_workspace_types.h" #include "DNA_userdef_types.h" #include "BKE_context.h" #include "BKE_customdata.h" +#include "BKE_fcurve.h" #include "BKE_global.h" +#include "BKE_icons.h" #include "BKE_main.h" #include "BKE_object.h" #include "BKE_report.h" @@ -61,10 +65,14 @@ #include "BKE_editmesh.h" #include "BKE_sound.h" #include "BKE_mask.h" +#include "BKE_workspace.h" #include "WM_api.h" #include "WM_types.h" +#include "DEG_depsgraph.h" + +#include "ED_anim_api.h" #include "ED_armature.h" #include "ED_clip.h" #include "ED_image.h" @@ -134,7 +142,7 @@ int ED_operator_screen_mainwinactive(bContext *C) if (CTX_wm_window(C) == NULL) return 0; screen = CTX_wm_screen(C); if (screen == NULL) return 0; - if (screen->subwinactive != screen->mainwin) return 0; + if (screen->active_region != NULL) return 0; return 1; } @@ -200,7 +208,7 @@ int ED_operator_animview_active(bContext *C) { if (ED_operator_areaactive(C)) { SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C); - if (sl && (ELEM(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_IPO, SPACE_TIME))) + if (sl && (ELEM(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_IPO))) return true; } @@ -208,11 +216,6 @@ int ED_operator_animview_active(bContext *C) return 0; } -int ED_operator_timeline_active(bContext *C) -{ - return ed_spacetype_test(C, SPACE_TIME); -} - int ED_operator_outliner_active(bContext *C) { return ed_spacetype_test(C, SPACE_OUTLINER); @@ -291,11 +294,6 @@ int ED_operator_nla_active(bContext *C) return ed_spacetype_test(C, SPACE_NLA); } -int ED_operator_logic_active(bContext *C) -{ - return ed_spacetype_test(C, SPACE_LOGIC); -} - int ED_operator_info_active(bContext *C) { return ed_spacetype_test(C, SPACE_INFO); @@ -552,8 +550,8 @@ int ED_operator_mask(bContext *C) case SPACE_IMAGE: { SpaceImage *sima = sa->spacedata.first; - Scene *scene = CTX_data_scene(C); - return ED_space_image_check_show_maskedit(scene, sima); + ViewLayer *view_layer = CTX_data_view_layer(C); + return ED_space_image_check_show_maskedit(sima, view_layer); } } } @@ -561,6 +559,12 @@ int ED_operator_mask(bContext *C) return false; } +int ED_operator_camera(bContext *C) +{ + struct Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data; + return (cam != NULL); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -723,6 +727,68 @@ static AZone *area_actionzone_refresh_xy(ScrArea *sa, const int xy[2], const boo break; } } + else if (az->type == AZONE_REGION_SCROLL) { + ARegion *ar = az->ar; + View2D *v2d = &ar->v2d; + const short isect_value = UI_view2d_mouse_in_scrollers(ar, v2d, xy[0], xy[1]); + if (test_only) { + if (isect_value != 0) { + break; + } + } + else { + bool redraw = false; + + if (isect_value == 'h') { + if (az->direction == AZ_SCROLL_HOR) { + az->alpha = 1.0f; + v2d->alpha_hor = 255; + v2d->size_hor = V2D_SCROLL_HEIGHT; + redraw = true; + } + } + else if (isect_value == 'v') { + if (az->direction == AZ_SCROLL_VERT) { + az->alpha = 1.0f; + v2d->alpha_vert = 255; + v2d->size_vert = V2D_SCROLL_WIDTH; + redraw = true; + } + } + else { + const int local_xy[2] = {xy[0] - ar->winrct.xmin, xy[1] - ar->winrct.ymin}; + float dist_fac = 0.0f, alpha = 0.0f; + + if (az->direction == AZ_SCROLL_HOR) { + dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN; + CLAMP(dist_fac, 0.0f, 1.0f); + alpha = 1.0f - dist_fac; + + v2d->alpha_hor = alpha * 255; + v2d->size_hor = round_fl_to_int( + V2D_SCROLL_HEIGHT - + ((V2D_SCROLL_HEIGHT - V2D_SCROLL_HEIGHT_MIN) * dist_fac)); + } + else if (az->direction == AZ_SCROLL_VERT) { + dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN; + CLAMP(dist_fac, 0.0f, 1.0f); + alpha = 1.0f - dist_fac; + + v2d->alpha_vert = alpha * 255; + v2d->size_vert = round_fl_to_int( + V2D_SCROLL_WIDTH - + ((V2D_SCROLL_WIDTH - V2D_SCROLL_WIDTH_MIN) * dist_fac)); + } + az->alpha = alpha; + redraw = true; + } + + if (redraw) { + ED_area_tag_redraw_no_rebuild(sa); + } + /* Don't return! */ + } + } } } @@ -794,6 +860,9 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event) actionzone_exit(op); return OPERATOR_FINISHED; } + else if (ELEM(sad->az->type, AZONE_REGION_SCROLL)) { + return OPERATOR_PASS_THROUGH; + } else { /* add modal handler */ WM_event_add_modal_handler(C, op); @@ -805,11 +874,8 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event) static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) { - wmWindow *win = CTX_wm_window(C); bScreen *sc = CTX_wm_screen(C); sActionzoneData *sad = op->customdata; - const int winsize_x = WM_window_pixels_x(win); - const int winsize_y = WM_window_pixels_y(win); switch (event->type) { case MOUSEMOVE: @@ -830,10 +896,15 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) sad->gesture_dir = 'w'; if (sad->az->type == AZONE_AREA) { + const wmWindow *win = CTX_wm_window(C); + rcti screen_rect; + + WM_window_screen_rect_calc(win, &screen_rect); /* once we drag outside the actionzone, register a gesture * check we're not on an edge so join finds the other area */ is_gesture = ((ED_area_actionzone_find_xy(sad->sa1, &event->x) != sad->az) && - (screen_find_active_scredge(sc, winsize_x, winsize_y, event->x, event->y) == NULL)); + (screen_area_map_find_active_scredge( + AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y) == NULL)); } else { const int delta_min = 1; @@ -1023,13 +1094,17 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot) static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Main *bmain = CTX_data_main(C); - wmWindow *newwin, *win; - bScreen *newsc, *sc; + wmWindow *newwin, *win = CTX_wm_window(C); + Scene *scene; + WorkSpace *workspace = WM_window_get_active_workspace(win); + WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); + WorkSpaceLayout *layout_new; + bScreen *newsc; ScrArea *sa; rcti rect; win = CTX_wm_window(C); - sc = CTX_wm_screen(C); + scene = CTX_data_scene(C); sa = CTX_wm_area(C); /* XXX hrmf! */ @@ -1056,9 +1131,13 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event) *newwin->stereo3d_format = *win->stereo3d_format; + newwin->scene = scene; + + WM_window_set_active_workspace(newwin, workspace); /* allocs new screen and adds to newly created window, using window size */ - newsc = ED_screen_add(bmain, newwin, CTX_data_scene(C), sc->id.name + 2); - newwin->screen = newsc; + layout_new = ED_workspace_layout_add(bmain, workspace, newwin, BKE_workspace_layout_name_get(layout_old)); + newsc = BKE_workspace_layout_screen_get(layout_new); + WM_window_set_active_layout(newwin, workspace, layout_new); /* copy area to new screen */ ED_area_data_copy((ScrArea *)newsc->areabase.first, sa, true); @@ -1126,32 +1205,82 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot) */ typedef struct sAreaMoveData { - int bigger, smaller, origval; + int bigger, smaller, origval, step; char dir; - bool do_snap; + enum AreaMoveSnapType { + /* Snapping disabled */ + SNAP_NONE = 0, + /* Snap to an invisible grid with a unit defined in AREAGRID */ + SNAP_AREAGRID, + /* Snap to mid-point and adjacent edges. */ + SNAP_MIDPOINT_AND_ADJACENT, + /* Snap to either bigger or smaller, nothing in-between (used for + * global areas). This has priority over other snap types, if it is + * used, toggling SNAP_MIDPOINT_AND_ADJACENT doesn't work. */ + SNAP_BIGGER_SMALLER_ONLY, + } snap_type; } sAreaMoveData; /* helper call to move area-edge, sets limits - * need window size in order to get correct limits */ -static void area_move_set_limits(bScreen *sc, int dir, - const int winsize_x, const int winsize_y, - int *bigger, int *smaller) + * need window bounds in order to get correct limits */ +static void area_move_set_limits( + wmWindow *win, bScreen *sc, int dir, + const rcti *screen_rect, + int *bigger, int *smaller, + bool *use_bigger_smaller_snap) { - ScrArea *sa; int areaminy = ED_area_headersize(); int areamin; /* we check all areas and test for free space with MINSIZE */ *bigger = *smaller = 100000; - for (sa = sc->areabase.first; sa; sa = sa->next) { + if (use_bigger_smaller_snap != NULL) { + *use_bigger_smaller_snap = false; + for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { + const int size_min = round_fl_to_int(area->global->size_min * UI_DPI_FAC); + const int size_max = round_fl_to_int(area->global->size_max * UI_DPI_FAC); + + /* logic here is only tested for lower edge :) */ + /* left edge */ + if ((area->v1->editflag && area->v2->editflag)) { + *smaller = area->v4->vec.x - size_max; + *bigger = area->v4->vec.x - size_min; + *use_bigger_smaller_snap = true; + return; + } + /* top edge */ + else if ((area->v2->editflag && area->v3->editflag)) { + *smaller = area->v1->vec.y + size_min; + *bigger = area->v1->vec.y + size_max; + *use_bigger_smaller_snap = true; + return; + } + /* right edge */ + else if ((area->v3->editflag && area->v4->editflag)) { + *smaller = area->v1->vec.x + size_min; + *bigger = area->v1->vec.x + size_max; + *use_bigger_smaller_snap = true; + return; + } + /* lower edge */ + else if ((area->v4->editflag && area->v1->editflag)) { + *smaller = area->v2->vec.y - size_max; + *bigger = area->v2->vec.y - size_min; + *use_bigger_smaller_snap = true; + return; + } + } + } + + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { if (dir == 'h') { int y1; areamin = areaminy; - if (sa->v1->vec.y > 0) + if (sa->v1->vec.y > screen_rect->ymin) areamin += U.pixelsize; - if (sa->v2->vec.y < winsize_y - 1) + if (sa->v2->vec.y < (screen_rect->ymax - 1)) areamin += U.pixelsize; y1 = sa->v2->vec.y - sa->v1->vec.y + 1 - areamin; @@ -1166,9 +1295,9 @@ static void area_move_set_limits(bScreen *sc, int dir, int x1; areamin = AREAMINX; - if (sa->v1->vec.x > 0) + if (sa->v1->vec.x > screen_rect->xmin) areamin += U.pixelsize; - if (sa->v4->vec.x < winsize_x - 1) + if (sa->v4->vec.x < (screen_rect->xmax - 1)) areamin += U.pixelsize; x1 = sa->v4->vec.x - sa->v1->vec.x + 1 - areamin; @@ -1190,9 +1319,7 @@ static int area_move_init(bContext *C, wmOperator *op) wmWindow *win = CTX_wm_window(C); ScrEdge *actedge; sAreaMoveData *md; - ScrVert *v1; - const int winsize_x = WM_window_pixels_x(win); - const int winsize_y = WM_window_pixels_y(win); + rcti screen_rect; int x, y; /* required properties */ @@ -1200,7 +1327,7 @@ static int area_move_init(bContext *C, wmOperator *op) y = RNA_int_get(op->ptr, "y"); /* setup */ - actedge = screen_find_active_scredge(sc, winsize_x, winsize_y, x, y); + actedge = screen_find_active_scredge(win, sc, x, y); if (actedge == NULL) return 0; md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData"); @@ -1210,42 +1337,67 @@ static int area_move_init(bContext *C, wmOperator *op) if (md->dir == 'h') md->origval = actedge->v1->vec.y; else md->origval = actedge->v1->vec.x; - select_connected_scredge(sc, actedge); - /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */ - for (v1 = sc->vertbase.first; v1; v1 = v1->next) + select_connected_scredge(win, actedge); + /* now all vertices with 'flag == 1' are the ones that can be moved. Move this to editflag */ + ED_screen_verts_iter(win, sc, v1) { v1->editflag = v1->flag; + } + + WM_window_screen_rect_calc(win, &screen_rect); - area_move_set_limits(sc, md->dir, winsize_x, winsize_y, &md->bigger, &md->smaller); + bool use_bigger_smaller_snap = false; + area_move_set_limits(win, sc, md->dir, &screen_rect, + &md->bigger, &md->smaller, + &use_bigger_smaller_snap); + + md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_AREAGRID; return 1; } static int area_snap_calc_location( - const bScreen *sc, const int delta, - const int origval, const int dir, + const bScreen *sc, const enum AreaMoveSnapType snap_type, + const int delta, const int origval, const int dir, const int bigger, const int smaller) { + BLI_assert(snap_type != SNAP_NONE); int final_loc = -1; - const int m_loc = origval + delta; - const int axis = (dir == 'v') ? 0 : 1; - int snap_dist; - int dist; - { - /* Test the snap to middle. */ - int middle = origval + (bigger - smaller) / 2; - middle -= (middle % AREAGRID); - snap_dist = abs(m_loc - middle); - final_loc = middle; - } + switch (snap_type) { + case SNAP_AREAGRID: + final_loc = m_loc; + if (delta != bigger && delta != -smaller) { + final_loc -= (m_loc % AREAGRID); + } + break; - for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) { - if (v1->editflag) { - const int v_loc = (&v1->vec.x)[!axis]; + case SNAP_BIGGER_SMALLER_ONLY: + final_loc = (m_loc >= bigger) ? bigger : smaller; + break; + + case SNAP_MIDPOINT_AND_ADJACENT: + { + const int axis = (dir == 'v') ? 0 : 1; + int snap_dist; + int dist; + { + /* Test the snap to middle. */ + int middle = origval + (bigger - smaller) / 2; + snap_dist = abs(m_loc - middle); + final_loc = middle; + } - for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) { - if (!v2->editflag) { + for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) { + if (!v1->editflag) { + continue; + } + const int v_loc = (&v1->vec.x)[!axis]; + + for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) { + if (v2->editflag) { + continue; + } if (v_loc == (&v2->vec.x)[!axis]) { const int v_loc2 = (&v2->vec.x)[axis]; /* Do not snap to the vertices at the ends. */ @@ -1259,7 +1411,10 @@ static int area_snap_calc_location( } } } + break; } + case SNAP_NONE: + break; } return final_loc; @@ -1270,29 +1425,26 @@ static void area_move_apply_do( const bContext *C, int delta, const int origval, const int dir, const int bigger, const int smaller, - const bool do_snap) + const enum AreaMoveSnapType snap_type) { + wmWindow *win = CTX_wm_window(C); bScreen *sc = CTX_wm_screen(C); - ScrVert *v1; bool doredraw = false; CLAMP(delta, -smaller, bigger); short final_loc = -1; - if (do_snap) { - final_loc = area_snap_calc_location(sc, delta, origval, dir, bigger, smaller); + if (snap_type == SNAP_NONE) { + final_loc = origval + delta; } else { - final_loc = origval + delta; - if (delta != bigger && delta != -smaller) { - final_loc -= (final_loc % AREAGRID); - } + final_loc = area_snap_calc_location(sc, snap_type, delta, origval, dir, bigger, smaller); } BLI_assert(final_loc != -1); short axis = (dir == 'v') ? 0 : 1; - for (v1 = sc->vertbase.first; v1; v1 = v1->next) { + ED_screen_verts_iter(win, sc, v1) { if (v1->editflag) { short oldval = (&v1->vec.x)[axis]; (&v1->vec.x)[axis] = final_loc; @@ -1307,12 +1459,26 @@ static void area_move_apply_do( /* only redraw if we actually moved a screen vert, for AREAGRID */ if (doredraw) { - for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + bool redraw_all = false; + ED_screen_areas_iter(win, sc, sa) { if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) { + if (ED_area_is_global(sa)) { + sa->global->cur_fixed_height = round_fl_to_int((sa->v2->vec.y - sa->v1->vec.y) / UI_DPI_FAC); + sc->do_refresh = true; + redraw_all = true; + } + ED_area_tag_redraw(sa); + } + } + if (redraw_all) { + ED_screen_areas_iter(win, sc, sa) { ED_area_tag_redraw(sa); } } + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */ + /* Update preview thumbnail */ + BKE_icon_changed(sc->id.icon_id); } } @@ -1321,7 +1487,7 @@ static void area_move_apply(bContext *C, wmOperator *op) sAreaMoveData *md = op->customdata; int delta = RNA_int_get(op->ptr, "delta"); - area_move_apply_do(C, delta, md->origval, md->dir, md->bigger, md->smaller, md->do_snap); + area_move_apply_do(C, delta, md->origval, md->dir, md->bigger, md->smaller, md->snap_type); } static void area_move_exit(bContext *C, wmOperator *op) @@ -1331,8 +1497,8 @@ static void area_move_exit(bContext *C, wmOperator *op) op->customdata = NULL; /* this makes sure aligned edges will result in aligned grabbing */ - removedouble_scrverts(CTX_wm_screen(C)); - removedouble_scredges(CTX_wm_screen(C)); + BKE_screen_remove_double_scrverts(CTX_wm_screen(C)); + BKE_screen_remove_double_scredges(CTX_wm_screen(C)); } static int area_move_exec(bContext *C, wmOperator *op) @@ -1400,10 +1566,15 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; case KM_MODAL_SNAP_ON: - md->do_snap = true; + if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) { + md->snap_type = SNAP_MIDPOINT_AND_ADJACENT; + } break; + case KM_MODAL_SNAP_OFF: - md->do_snap = false; + if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) { + md->snap_type = SNAP_AREAGRID; + } break; } break; @@ -1522,7 +1693,7 @@ static int area_split_init(bContext *C, wmOperator *op) { ScrArea *sa = CTX_wm_area(C); sAreaSplitData *sd; - int areaminy = ED_area_headersize() + 1; + int areaminy = ED_area_headersize(); int dir; /* required context */ @@ -1540,8 +1711,14 @@ static int area_split_init(bContext *C, wmOperator *op) op->customdata = sd; sd->sarea = sa; - sd->origsize = dir == 'v' ? sa->winx : sa->winy; - sd->origmin = dir == 'v' ? sa->totrct.xmin : sa->totrct.ymin; + if (dir == 'v') { + sd->origmin = sa->v1->vec.x; + sd->origsize = sa->v4->vec.x - sd->origmin; + } + else { + sd->origmin = sa->v1->vec.y; + sd->origsize = sa->v2->vec.y - sd->origmin; + } return 1; } @@ -1560,16 +1737,16 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb) ScrVert *sbv4 = sb->v4; if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */ - return screen_findedge(screen, sav1, sav2); + return BKE_screen_find_edge(screen, sav1, sav2); } else if (sav2 == sbv1 && sav3 == sbv4) { /* sa to bottom of sb = N */ - return screen_findedge(screen, sav2, sav3); + return BKE_screen_find_edge(screen, sav2, sav3); } else if (sav3 == sbv2 && sav4 == sbv1) { /* sa to left of sb = E */ - return screen_findedge(screen, sav3, sav4); + return BKE_screen_find_edge(screen, sav3, sav4); } else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/ - return screen_findedge(screen, sav1, sav4); + return BKE_screen_find_edge(screen, sav1, sav4); } return NULL; @@ -1608,6 +1785,8 @@ static int area_split_apply(bContext *C, wmOperator *op) ED_area_tag_redraw(sd->narea); WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + /* Update preview thumbnail */ + BKE_icon_changed(sc->id.icon_id); return 1; } @@ -1633,8 +1812,8 @@ static void area_split_exit(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* this makes sure aligned edges will result in aligned grabbing */ - removedouble_scrverts(CTX_wm_screen(C)); - removedouble_scredges(CTX_wm_screen(C)); + BKE_screen_remove_double_scrverts(CTX_wm_screen(C)); + BKE_screen_remove_double_scredges(CTX_wm_screen(C)); } static void area_split_preview_update_cursor(bContext *C, wmOperator *op) @@ -1650,14 +1829,15 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) wmWindow *win = CTX_wm_window(C); bScreen *sc = CTX_wm_screen(C); sAreaSplitData *sd; - const int winsize_x = WM_window_pixels_x(win); - const int winsize_y = WM_window_pixels_y(win); + rcti screen_rect; int dir; /* no full window splitting allowed */ if (sc->state != SCREENNORMAL) return OPERATOR_CANCELLED; + WM_window_screen_rect_calc(win, &screen_rect); + if (event->type == EVT_ACTIONZONE_AREA) { sActionzoneData *sad = event->customdata; @@ -1704,7 +1884,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) else y = event->x; - actedge = screen_find_active_scredge(sc, winsize_x, winsize_y, x, y); + actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, x, y); if (actedge == NULL) return OPERATOR_CANCELLED; @@ -1724,7 +1904,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* do the split */ if (area_split_apply(C, op)) { - area_move_set_limits(sc, dir, winsize_x, winsize_y, &sd->bigger, &sd->smaller); + area_move_set_limits(win, sc, dir, &screen_rect, &sd->bigger, &sd->smaller, NULL); /* add temp handler for edge move or cancel */ WM_event_add_modal_handler(C, op); @@ -1842,10 +2022,11 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) if (sd->previewmode == 0) { if (sd->do_snap) { const int snap_loc = area_snap_calc_location( - CTX_wm_screen(C), sd->delta, sd->origval, dir, sd->bigger, sd->smaller); + CTX_wm_screen(C), SNAP_MIDPOINT_AND_ADJACENT, sd->delta, sd->origval, dir, + sd->bigger, sd->smaller); sd->delta = snap_loc - sd->origval; } - area_move_apply_do(C, sd->delta, sd->origval, dir, sd->bigger, sd->smaller, false); + area_move_apply_do(C, sd->delta, sd->origval, dir, sd->bigger, sd->smaller, SNAP_NONE); } else { if (sd->sarea) { @@ -1857,19 +2038,20 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) if (sd->sarea) { ScrArea *sa = sd->sarea; if (dir == 'v') { - sd->origsize = sa->winx; - sd->origmin = sa->totrct.xmin; + sd->origmin = sa->v1->vec.x; + sd->origsize = sa->v4->vec.x - sd->origmin; } else { - sd->origsize = sa->winy; - sd->origmin = sa->totrct.ymin; + sd->origmin = sa->v1->vec.y; + sd->origsize = sa->v2->vec.y - sd->origmin; } if (sd->do_snap) { sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 1; const int snap_loc = area_snap_calc_location( - CTX_wm_screen(C), sd->delta, sd->origval, dir, sd->origmin + sd->origsize, -sd->origmin); + CTX_wm_screen(C), SNAP_MIDPOINT_AND_ADJACENT, sd->delta, sd->origval, dir, + sd->origmin + sd->origsize, -sd->origmin); sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 0; sd->delta = snap_loc - sd->origval; @@ -1878,7 +2060,7 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) ED_area_tag_redraw(sd->sarea); } - CTX_wm_window(C)->screen->do_draw = true; + CTX_wm_screen(C)->do_draw = true; } float fac = (float)(sd->delta + sd->origval - sd->origmin) / sd->origsize; @@ -2047,7 +2229,8 @@ static int region_scale_get_maxsize(RegionMoveData *rmd) if (rmd->ar->regiontype == RGN_TYPE_TOOL_PROPS) { /* this calculation seems overly verbose * can someone explain why this method is necessary? - campbell */ - maxsize = rmd->maxsize - ((rmd->sa->headertype == HEADERTOP) ? UI_UNIT_Y * 2 : UI_UNIT_Y) - (UI_UNIT_Y / 4); + const bool top_header = ED_area_header_alignment(rmd->sa) == RGN_ALIGN_TOP; + maxsize = rmd->maxsize - ((top_header) ? UI_UNIT_Y * 2 : UI_UNIT_Y) - (UI_UNIT_Y / 4); } return maxsize; @@ -2091,7 +2274,9 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) /* execute the events */ switch (event->type) { case MOUSEMOVE: - + { + const float aspect = BLI_rctf_size_x(&rmd->ar->v2d.cur) / (BLI_rcti_size_x(&rmd->ar->v2d.mask) + 1); + const int snap_size_threshold = (U.widget_unit * 2) / aspect; if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { delta = event->x - rmd->origx; if (rmd->edge == AE_LEFT_TO_TOPRIGHT) delta = -delta; @@ -2100,6 +2285,13 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) delta /= UI_DPI_FAC; rmd->ar->sizex = rmd->origval + delta; + + if (rmd->ar->type->snap_size) { + short sizex_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizex, 0); + if (ABS(rmd->ar->sizex - sizex_test) < snap_size_threshold) { + rmd->ar->sizex = sizex_test; + } + } CLAMP(rmd->ar->sizex, 0, rmd->maxsize); if (rmd->ar->sizex < UI_UNIT_X) { @@ -2119,6 +2311,13 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) delta /= UI_DPI_FAC; rmd->ar->sizey = rmd->origval + delta; + + if (rmd->ar->type->snap_size) { + short sizey_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizey, 1); + if (ABS(rmd->ar->sizey - sizey_test) < snap_size_threshold) { + rmd->ar->sizey = sizey_test; + } + } CLAMP(rmd->ar->sizey, 0, rmd->maxsize); /* note, 'UI_UNIT_Y/4' means you need to drag the header almost @@ -2138,7 +2337,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); break; - + } case LEFTMOUSE: if (event->val == KM_RELEASE) { @@ -2201,16 +2400,15 @@ static void areas_do_frame_follow(bContext *C, bool middle) bScreen *scr = CTX_wm_screen(C); Scene *scene = CTX_data_scene(C); wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *window; - for (window = wm->windows.first; window; window = window->next) { - ScrArea *sa; - for (sa = window->screen->areabase.first; sa; sa = sa->next) { - ARegion *ar; - for (ar = sa->regionbase.first; ar; ar = ar->next) { + for (wmWindow *window = wm->windows.first; window; window = window->next) { + const bScreen *screen = WM_window_get_active_screen(window); + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { /* do follow here if editor type supports it */ if ((scr->redraws_flag & TIME_FOLLOW)) { if ((ar->regiontype == RGN_TYPE_WINDOW && - ELEM(sa->spacetype, SPACE_SEQ, SPACE_TIME, SPACE_IPO, SPACE_ACTION, SPACE_NLA)) || + ELEM(sa->spacetype, SPACE_SEQ, SPACE_IPO, SPACE_ACTION, SPACE_NLA)) || (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW)) { float w = BLI_rctf_size_x(&ar->v2d.cur); @@ -2521,64 +2719,16 @@ static void SCREEN_OT_marker_jump(wmOperatorType *ot) /** \name Set Screen Operator * \{ */ -static bool screen_set_is_ok(bScreen *screen, bScreen *screen_prev) -{ - return ((screen->winid == 0) && - /* in typical usage these should have a nonzero winid - * (all temp screens should be used, or closed & freed). */ - (screen->temp == false) && - (screen->state == SCREENNORMAL) && - (screen != screen_prev) && - (screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT))); -} - /* function to be called outside UI context, or for redo */ static int screen_set_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - bScreen *screen = CTX_wm_screen(C); - bScreen *screen_prev = screen; - - ScrArea *sa = CTX_wm_area(C); - int tot = BLI_listbase_count(&bmain->screen); + WorkSpace *workspace = CTX_wm_workspace(C); int delta = RNA_int_get(op->ptr, "delta"); - /* temp screens are for userpref or render display */ - if (screen->temp || (sa && sa->full && sa->full->temp)) { - return OPERATOR_CANCELLED; - } - - if (delta == 1) { - while (tot--) { - screen = screen->id.next; - if (screen == NULL) screen = bmain->screen.first; - if (screen_set_is_ok(screen, screen_prev)) { - break; - } - } - } - else if (delta == -1) { - while (tot--) { - screen = screen->id.prev; - if (screen == NULL) screen = bmain->screen.last; - if (screen_set_is_ok(screen, screen_prev)) { - break; - } - } - } - else { - screen = NULL; - } - - if (screen && screen_prev != screen) { - /* return to previous state before switching screens */ - if (sa && sa->full) { - ED_screen_full_restore(C, sa); /* may free 'screen_prev' */ - } - - ED_screen_set(C, screen); + if (ED_workspace_layout_cycle(workspace, delta, C)) { return OPERATOR_FINISHED; } + return OPERATOR_CANCELLED; } @@ -2634,6 +2784,15 @@ static int screen_maximize_area_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int screen_maximize_area_poll(bContext *C) +{ + const bScreen *screen = CTX_wm_screen(C); + const ScrArea *area = CTX_wm_area(C); + return ED_operator_areaactive(C) && + /* Don't allow maximizing global areas but allow minimizing from them. */ + ((screen->state != SCREENNORMAL) || !ED_area_is_global(area)); +} + static void SCREEN_OT_screen_full_area(wmOperatorType *ot) { PropertyRNA *prop; @@ -2643,7 +2802,7 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot) ot->idname = "SCREEN_OT_screen_full_area"; ot->exec = screen_maximize_area_exec; - ot->poll = ED_operator_areaactive; + ot->poll = screen_maximize_area_poll; ot->flag = 0; prop = RNA_def_boolean(ot->srna, "use_hide_panels", false, "Hide Panels", "Hide all the panels"); @@ -2776,9 +2935,9 @@ static void area_join_exit(bContext *C, wmOperator *op) } /* this makes sure aligned edges will result in aligned grabbing */ - removedouble_scredges(CTX_wm_screen(C)); - removenotused_scredges(CTX_wm_screen(C)); - removenotused_scrverts(CTX_wm_screen(C)); + BKE_screen_remove_double_scredges(CTX_wm_screen(C)); + BKE_screen_remove_unused_scredges(CTX_wm_screen(C)); + BKE_screen_remove_unused_scrverts(CTX_wm_screen(C)); } static int area_join_exec(bContext *C, wmOperator *op) @@ -2947,16 +3106,16 @@ static void SCREEN_OT_area_join(wmOperatorType *ot) static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - wmWindow *win = CTX_wm_window(C); - bScreen *sc = CTX_wm_screen(C); + const wmWindow *win = CTX_wm_window(C); + const bScreen *sc = CTX_wm_screen(C); uiPopupMenu *pup; uiLayout *layout; PointerRNA ptr; ScrEdge *actedge; - const int winsize_x = WM_window_pixels_x(win); - const int winsize_y = WM_window_pixels_y(win); + rcti screen_rect; - actedge = screen_find_active_scredge(sc, winsize_x, winsize_y, event->x, event->y); + WM_window_screen_rect_calc(win, &screen_rect); + actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y); if (actedge == NULL) return OPERATOR_CANCELLED; @@ -3360,6 +3519,18 @@ static int region_flip_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +static int region_flip_poll(bContext *C) +{ + ScrArea *area = CTX_wm_area(C); + + /* don't flip anything around in topbar */ + if (area->spacetype == SPACE_TOPBAR) { + CTX_wm_operator_poll_msg_set(C, "Flipping regions in the Top-bar is not allowed"); + return 0; + } + + return ED_operator_areaactive(C); +} static void SCREEN_OT_region_flip(wmOperatorType *ot) { @@ -3370,7 +3541,7 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot) /* api callbacks */ ot->exec = region_flip_exec; - ot->poll = ED_operator_areaactive; + ot->poll = region_flip_poll; ot->flag = 0; } @@ -3453,6 +3624,8 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN 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 Header"), ICON_NONE, "SCREEN_OT_header"); + /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); @@ -3463,12 +3636,11 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN uiItemS(layout); - /* file browser should be fullscreen all the time, but other regions can be maximized/restored... */ - if (sa->spacetype != SPACE_FILE) { - if (sa->full) - uiItemO(layout, IFACE_("Tile Area"), ICON_NONE, "SCREEN_OT_screen_full_area"); - else - uiItemO(layout, IFACE_("Maximize Area"), ICON_NONE, "SCREEN_OT_screen_full_area"); + /* 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)) { + const char *but_str = sa->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); + uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); } } @@ -3528,13 +3700,14 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws, return 1; break; case SPACE_IPO: - case SPACE_ACTION: case SPACE_NLA: if ((redraws & TIME_ALL_ANIM_WIN) || from_anim_edit) return 1; break; - case SPACE_TIME: - /* if only 1 window or 3d windows, we do timeline too */ + case SPACE_ACTION: + /* if only 1 window or 3d windows, we do timeline too + * NOTE: Now we do do action editor in all these cases, since timeline is here + */ if ((redraws & (TIME_ALL_ANIM_WIN | TIME_REGION | TIME_ALL_3D_WIN)) || from_anim_edit) return 1; break; @@ -3585,7 +3758,7 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws, return 1; } else if (regiontype == RGN_TYPE_HEADER) { - if (spacetype == SPACE_TIME) + if (spacetype == SPACE_ACTION) return 1; } else if (regiontype == RGN_TYPE_PREVIEW) { @@ -3615,6 +3788,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv if (screen->animtimer && screen->animtimer == event->customdata) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + struct Depsgraph *depsgraph = CTX_data_depsgraph(C); wmTimer *wt = screen->animtimer; ScreenAnimData *sad = wt->customdata; wmWindowManager *wm = CTX_wm_manager(C); @@ -3725,10 +3899,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv } /* since we follow drawflags, we can't send notifier but tag regions ourselves */ - ED_update_for_newframe(bmain, scene, 1); + ED_update_for_newframe(bmain, depsgraph); for (window = wm->windows.first; window; window = window->next) { - for (sa = window->screen->areabase.first; sa; sa = sa->next) { + const bScreen *win_screen = WM_window_get_active_screen(window); + + for (sa = win_screen->areabase.first; sa; sa = sa->next) { ARegion *ar; for (ar = sa->regionbase.first; ar; ar = ar->next) { bool redraw = false; @@ -3744,7 +3920,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv /* do follow here if editor type supports it */ if ((sad->redraws & TIME_FOLLOW)) { if ((ar->regiontype == RGN_TYPE_WINDOW && - ELEM(sa->spacetype, SPACE_SEQ, SPACE_TIME, SPACE_IPO, SPACE_ACTION, SPACE_NLA)) || + ELEM(sa->spacetype, SPACE_SEQ, SPACE_IPO, SPACE_ACTION, SPACE_NLA)) || (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW)) { float w = BLI_rctf_size_x(&ar->v2d.cur); @@ -3808,11 +3984,11 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot) /* find window that owns the animation timer */ bScreen *ED_screen_animation_playing(const wmWindowManager *wm) { - wmWindow *win; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + bScreen *screen = WM_window_get_active_screen(win); - for (win = wm->windows.first; win; win = win->next) { - if (win->screen->animtimer || win->screen->scrubbing) { - return win->screen; + if (screen->animtimer || screen->scrubbing) { + return screen; } } @@ -3821,11 +3997,11 @@ bScreen *ED_screen_animation_playing(const wmWindowManager *wm) bScreen *ED_screen_animation_no_scrub(const wmWindowManager *wm) { - wmWindow *win; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + bScreen *screen = WM_window_get_active_screen(win); - for (win = wm->windows.first; win; win = win->next) { - if (win->screen->animtimer) { - return win->screen; + if (screen->animtimer) { + return screen; } } @@ -3847,7 +4023,7 @@ int ED_screen_animation_play(bContext *C, int sync, int mode) WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } else { - int refresh = SPACE_TIME; /* these settings are currently only available from a menu in the TimeLine */ + int refresh = SPACE_ACTION; /* these settings are currently only available from a menu in the TimeLine */ if (mode == 1) /* XXX only play audio forwards!? */ BKE_sound_play_scene(scene); @@ -4049,7 +4225,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot) static int userpref_show_invoke(bContext *C, wmOperator *op, const wmEvent *event) { int sizex = 800 * UI_DPI_FAC; - int sizey = 480 * UI_DPI_FAC; + int sizey = 500 * UI_DPI_FAC; /* changes context! */ if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_USERPREFS) != NULL) { @@ -4077,118 +4253,101 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name New Screen Operator +/** \name Show Drivers Editor Operator * \{ */ -static int screen_new_exec(bContext *C, wmOperator *UNUSED(op)) +static int drivers_editor_show_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Main *bmain = CTX_data_main(C); - wmWindow *win = CTX_wm_window(C); - bScreen *sc = CTX_wm_screen(C); + PointerRNA ptr = {{NULL}}; + PropertyRNA *prop = NULL; + int index = -1; + uiBut *but = NULL; - sc = ED_screen_duplicate(bmain, win, sc); - WM_event_add_notifier(C, NC_SCREEN | ND_SCREENBROWSE, sc); + int sizex = 900 * UI_DPI_FAC; + int sizey = 580 * UI_DPI_FAC; - return OPERATOR_FINISHED; -} + /* Get active property to show driver for + * - Need to grab it first, or else this info disappears + * after we've created the window + */ + but = UI_context_active_but_prop_get(C, &ptr, &prop, &index); -static void SCREEN_OT_new(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "New Screen"; - ot->description = "Add a new screen"; - ot->idname = "SCREEN_OT_new"; + /* changes context! */ + if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_DRIVERS) != NULL) { + /* activate driver F-Curve for the property under the cursor */ + if (but) { + FCurve *fcu; + bool driven, special; + + fcu = rna_get_fcurve_context_ui(C, + &ptr, prop, index, + NULL, NULL, &driven, &special); + if (fcu) { + /* Isolate this F-Curve... */ + bAnimContext ac; + if (ANIM_animdata_get_context(C, &ac)) { + int filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS; + ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ANIM_set_active_channel(&ac, ac.data, ac.datatype, filter, fcu, ANIMTYPE_FCURVE); + } + else { + /* Just blindly isolate... This isn't the best, and shouldn't happen, but may be enough... */ + fcu->flag |= (FCURVE_ACTIVE | FCURVE_SELECTED); + } + } + } - /* api callbacks */ - ot->exec = screen_new_exec; - ot->poll = WM_operator_winactive; + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); + return OPERATOR_CANCELLED; + } } -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Delete Screen Operator - * \{ */ - -static int screen_delete_exec(bContext *C, wmOperator *UNUSED(op)) -{ - bScreen *sc = CTX_wm_screen(C); - - WM_event_add_notifier(C, NC_SCREEN | ND_SCREENDELETE, sc); - - return OPERATOR_FINISHED; -} -static void SCREEN_OT_delete(wmOperatorType *ot) +static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot) { /* identifiers */ - ot->name = "Delete Screen"; - ot->description = "Delete active screen"; - ot->idname = "SCREEN_OT_delete"; + ot->name = "Show Drivers Editor"; + ot->description = "Show drivers editor in a separate window"; + ot->idname = "SCREEN_OT_drivers_editor_show"; /* api callbacks */ - ot->exec = screen_delete_exec; + ot->invoke = drivers_editor_show_invoke; + ot->poll = ED_operator_screenactive; } /** \} */ /* -------------------------------------------------------------------- */ -/** \name New Scene Operator +/** \name New Screen Operator * \{ */ -static int scene_new_exec(bContext *C, wmOperator *op) +static int screen_new_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *newscene, *scene = CTX_data_scene(C); Main *bmain = CTX_data_main(C); - int type = RNA_enum_get(op->ptr, "type"); - - if (type == SCE_COPY_NEW) { - newscene = BKE_scene_add(bmain, DATA_("Scene")); - } - else { /* different kinds of copying */ - newscene = BKE_scene_copy(bmain, scene, type); - - /* these can't be handled in blenkernel currently, so do them here */ - if (type == SCE_COPY_LINK_DATA) { - ED_object_single_users(bmain, newscene, false, true); - } - else if (type == SCE_COPY_FULL) { - ED_editors_flush_edits(C, false); - ED_object_single_users(bmain, newscene, true, true); - } - } - - ED_screen_set_scene(C, CTX_wm_screen(C), newscene); + wmWindow *win = CTX_wm_window(C); + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + WorkSpaceLayout *layout_old = BKE_workspace_active_layout_get(win->workspace_hook); + WorkSpaceLayout *layout_new; - WM_event_add_notifier(C, NC_SCENE | ND_SCENEBROWSE, newscene); + layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win); + WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTBROWSE, layout_new); return OPERATOR_FINISHED; } -static void SCENE_OT_new(wmOperatorType *ot) +static void SCREEN_OT_new(wmOperatorType *ot) { - static const EnumPropertyItem type_items[] = { - {SCE_COPY_NEW, "NEW", 0, "New", "Add new scene"}, - {SCE_COPY_EMPTY, "EMPTY", 0, "Copy Settings", "Make a copy without any objects"}, - {SCE_COPY_LINK_OB, "LINK_OBJECTS", 0, "Link Objects", "Link to the objects from the current scene"}, - {SCE_COPY_LINK_DATA, "LINK_OBJECT_DATA", 0, "Link Object Data", "Copy objects linked to data from the current scene"}, - {SCE_COPY_FULL, "FULL_COPY", 0, "Full Copy", "Make a full copy of the current scene"}, - {0, NULL, 0, NULL, NULL}}; - /* identifiers */ - ot->name = "New Scene"; - ot->description = "Add new scene by type"; - ot->idname = "SCENE_OT_new"; + ot->name = "New Screen"; + ot->description = "Add a new screen"; + ot->idname = "SCREEN_OT_new"; /* api callbacks */ - ot->exec = scene_new_exec; - ot->invoke = WM_menu_invoke; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", ""); + ot->exec = screen_new_exec; + ot->poll = WM_operator_winactive; } /** \} */ @@ -4197,34 +4356,26 @@ static void SCENE_OT_new(wmOperatorType *ot) /** \name Delete Screen Operator * \{ */ -static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op)) +static int screen_delete_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene = CTX_data_scene(C); - - if (ED_screen_delete_scene(C, scene) == false) { - return OPERATOR_CANCELLED; - } - - if (G.debug & G_DEBUG) - printf("scene delete %p\n", scene); + bScreen *sc = CTX_wm_screen(C); + WorkSpace *workspace = CTX_wm_workspace(C); + WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, sc); - WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, scene); + WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTDELETE, layout); return OPERATOR_FINISHED; } -static void SCENE_OT_delete(wmOperatorType *ot) +static void SCREEN_OT_delete(wmOperatorType *ot) { /* identifiers */ - ot->name = "Delete Scene"; - ot->description = "Delete active scene"; - ot->idname = "SCENE_OT_delete"; + ot->name = "Delete Screen"; + ot->description = "Delete active screen"; + ot->idname = "SCREEN_OT_delete"; /* api callbacks */ - ot->exec = scene_delete_exec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->exec = screen_delete_exec; } /** \} */ @@ -4246,7 +4397,7 @@ typedef struct RegionAlphaInfo { #define TIMEOUT 0.2f #define TIMESTEP 0.04f -float ED_region_blend_factor(ARegion *ar) +float ED_region_blend_alpha(ARegion *ar) { /* check parent too */ if (ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) { @@ -4432,11 +4583,10 @@ static int space_context_cycle_invoke(bContext *C, wmOperator *op, const wmEvent PointerRNA ptr; PropertyRNA *prop; context_cycle_prop_get(CTX_wm_screen(C), CTX_wm_area(C), &ptr, &prop); - const int old_context = RNA_property_enum_get(&ptr, prop); const int new_context = RNA_property_enum_step( - C, &ptr, prop, old_context, - direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1); + C, &ptr, prop, old_context, + direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1); RNA_property_enum_set(&ptr, prop, new_context); RNA_property_update(C, &ptr, prop); @@ -4463,6 +4613,51 @@ static void SCREEN_OT_space_context_cycle(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Workspace Cycle Operator + * \{ */ + +static int space_workspace_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + wmWindow *win = CTX_wm_window(C); + if (WM_window_is_temp_screen(win)) { + return OPERATOR_CANCELLED; + } + + Main *bmain = CTX_data_main(C); + const int direction = RNA_enum_get(op->ptr, "direction"); + WorkSpace *workspace_src = WM_window_get_active_workspace(win); + WorkSpace *workspace_dst = (direction == SPACE_CONTEXT_CYCLE_PREV) ? workspace_src->id.prev : workspace_src->id.next; + if (workspace_dst == NULL) { + workspace_dst = (direction == SPACE_CONTEXT_CYCLE_PREV) ? bmain->workspaces.last : bmain->workspaces.first; + } + if (workspace_src != workspace_dst) { + win->workspace_hook->temp_workspace_store = workspace_dst; + WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace_dst); + win->workspace_hook->temp_workspace_store = NULL; + } + return OPERATOR_FINISHED; +} + +static void SCREEN_OT_workspace_cycle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Cycle Workspace"; + ot->description = "Cycle through workspaces"; + ot->idname = "SCREEN_OT_workspace_cycle"; + + /* api callbacks */ + ot->invoke = space_workspace_cycle_invoke; + ot->poll = ED_operator_screenactive;; + + ot->flag = 0; + + RNA_def_enum(ot->srna, "direction", space_context_cycle_direction, SPACE_CONTEXT_CYCLE_NEXT, "Direction", + "Direction to cycle through"); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Assigning Operator Types * \{ */ @@ -4495,8 +4690,10 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_screenshot); WM_operatortype_append(SCREEN_OT_screencast); WM_operatortype_append(SCREEN_OT_userpref_show); + WM_operatortype_append(SCREEN_OT_drivers_editor_show); WM_operatortype_append(SCREEN_OT_region_blend); WM_operatortype_append(SCREEN_OT_space_context_cycle); + WM_operatortype_append(SCREEN_OT_workspace_cycle); /*frame changes*/ WM_operatortype_append(SCREEN_OT_frame_offset); @@ -4511,8 +4708,6 @@ void ED_operatortypes_screen(void) /* new/delete */ WM_operatortype_append(SCREEN_OT_new); WM_operatortype_append(SCREEN_OT_delete); - WM_operatortype_append(SCENE_OT_new); - WM_operatortype_append(SCENE_OT_delete); /* tools shared by more space types */ WM_operatortype_append(ED_OT_undo); @@ -4618,10 +4813,8 @@ void ED_keymap_screen(wmKeyConfig *keyconf) RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1); - 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); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "use_hide_panels", true); WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0); @@ -4632,9 +4825,14 @@ void ED_keymap_screen(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "SCREEN_OT_space_context_cycle", TABKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_PREV); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_workspace_cycle", TABKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_NEXT); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_workspace_cycle", TABKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_PREV); + /* tests */ WM_keymap_add_item(keymap, "SCREEN_OT_region_quadview", QKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); - WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", RKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0); |