From be9842f65b85d64ab8b7baa686ded9c79c31227e Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Mon, 22 Feb 2021 11:37:25 -0800 Subject: UI: Simplify Window Creation Refactoring: WM_window_open() that can open different types of windows. 'New Window' with simplified layout. Differential Revision: https://developer.blender.org/D10419 Reviewed by Brecht Van Lommel --- source/blender/editors/render/render_view.c | 12 ++- source/blender/editors/screen/screen_edit.c | 11 ++- source/blender/editors/screen/screen_ops.c | 123 +++++++++++------------- source/blender/windowmanager/WM_api.h | 27 ++++-- source/blender/windowmanager/intern/wm_window.c | 122 ++++++++++++----------- 5 files changed, 151 insertions(+), 144 deletions(-) (limited to 'source') diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c index fd5963b217b..465438f814a 100644 --- a/source/blender/editors/render/render_view.c +++ b/source/blender/editors/render/render_view.c @@ -157,8 +157,16 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports) } /* changes context! */ - if (WM_window_open_temp( - C, IFACE_("Blender Render"), mx, my, sizex, sizey, SPACE_IMAGE, false) == NULL) { + if (WM_window_open(C, + IFACE_("Blender Render"), + mx, + my, + sizex, + sizey, + SPACE_IMAGE, + false, + true, + WIN_ALIGN_LOCATION_CENTER) == NULL) { BKE_report(reports, RPT_ERROR, "Failed to open window!"); return NULL; } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 1735b02ffe3..3e498522071 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1441,7 +1441,16 @@ ScrArea *ED_screen_temp_space_open(bContext *C, switch (display_type) { case USER_TEMP_SPACE_DISPLAY_WINDOW: - if (WM_window_open_temp(C, title, x, y, sizex, sizey, (int)space_type, dialog)) { + if (WM_window_open(C, + title, + x, + y, + sizex, + sizey, + (int)space_type, + dialog, + true, + WIN_ALIGN_LOCATION_CENTER)) { area = CTX_wm_area(C); } break; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 47feb49bd44..8a53154cc85 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1332,67 +1332,46 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot) /* operator callback */ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Main *bmain = CTX_data_main(C); - wmWindow *win = CTX_wm_window(C); - WorkSpace *workspace = WM_window_get_active_workspace(win); - WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); - - Scene *scene = CTX_data_scene(C); ScrArea *area = CTX_wm_area(C); - /* XXX hrmf! */ - if (event->type == EVT_ACTIONZONE_AREA) { + if (event && event->customdata) { sActionzoneData *sad = event->customdata; - if (sad == NULL) { return OPERATOR_PASS_THROUGH; } - area = sad->sa1; } - /* adds window to WM */ - rcti rect = area->totrct; - BLI_rcti_translate(&rect, win->posx, win->posy); - rect.xmax = rect.xmin + BLI_rcti_size_x(&rect); - rect.ymax = rect.ymin + BLI_rcti_size_y(&rect); + /* Create new window. No need to set space_type since it will be copied over. */ + wmWindow *newwin = WM_window_open(C, + "Blender", + area->totrct.xmin, + area->totrct.ymin, + area->winx, + area->winy, + SPACE_EMPTY, + true, + false, + WIN_ALIGN_ABSOLUTE); - wmWindow *newwin = WM_window_open(C, &rect); - if (newwin == NULL) { + if (newwin) { + /* copy area to new screen */ + bScreen *newsc = WM_window_get_active_screen(newwin); + ED_area_data_copy((ScrArea *)newsc->areabase.first, area, true); + ED_area_tag_redraw((ScrArea *)newsc->areabase.first); + + /* screen, areas init */ + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + } + else { BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); - goto finally; } - *newwin->stereo3d_format = *win->stereo3d_format; - - newwin->scene = scene; - - STRNCPY(newwin->view_layer_name, win->view_layer_name); - - BKE_workspace_active_set(newwin->workspace_hook, workspace); - /* allocs new screen and adds to newly created window, using window size */ - WorkSpaceLayout *layout_new = ED_workspace_layout_add( - bmain, workspace, newwin, BKE_workspace_layout_name_get(layout_old)); - bScreen *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, area, true); - - ED_area_tag_redraw((ScrArea *)newsc->areabase.first); - - /* screen, areas init */ - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - -finally: - if (event->type == EVT_ACTIONZONE_AREA) { + if (event && event->customdata) { actionzone_exit(op); } - if (newwin) { - return OPERATOR_FINISHED; - } - return OPERATOR_CANCELLED; + return newwin ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } static void SCREEN_OT_area_dupli(wmOperatorType *ot) @@ -4866,14 +4845,16 @@ static int userpref_show_exec(bContext *C, wmOperator *op) int sizey = 520 * UI_DPI_FAC; /* changes context! */ - if (WM_window_open_temp(C, - IFACE_("Blender Preferences"), - event->x, - event->y, - sizex, - sizey, - SPACE_USERPREF, - false) != NULL) { + if (WM_window_open(C, + IFACE_("Blender Preferences"), + event->x, + event->y, + sizex, + sizey, + SPACE_USERPREF, + false, + true, + WIN_ALIGN_LOCATION_CENTER) != NULL) { /* The header only contains the editor switcher and looks empty. * So hiding in the temp window makes sense. */ ScrArea *area = CTX_wm_area(C); @@ -4925,14 +4906,16 @@ static int drivers_editor_show_exec(bContext *C, wmOperator *op) uiBut *but = UI_context_active_but_prop_get(C, &ptr, &prop, &index); /* changes context! */ - if (WM_window_open_temp(C, - IFACE_("Blender Drivers Editor"), - event->x, - event->y, - sizex, - sizey, - SPACE_GRAPH, - false) != NULL) { + if (WM_window_open(C, + IFACE_("Blender Drivers Editor"), + event->x, + event->y, + sizex, + sizey, + SPACE_GRAPH, + false, + true, + WIN_ALIGN_LOCATION_CENTER) != NULL) { ED_drivers_editor_init(C, CTX_wm_area(C)); /* activate driver F-Curve for the property under the cursor */ @@ -4991,14 +4974,16 @@ static int info_log_show_exec(bContext *C, wmOperator *op) int shift_y = 480; /* changes context! */ - if (WM_window_open_temp(C, - IFACE_("Blender Info Log"), - event->x, - event->y + shift_y, - sizex, - sizey, - SPACE_INFO, - false) != NULL) { + if (WM_window_open(C, + IFACE_("Blender Info Log"), + event->x, + event->y + shift_y, + sizex, + sizey, + SPACE_INFO, + false, + true, + WIN_ALIGN_LOCATION_CENTER) != NULL) { return OPERATOR_FINISHED; } BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index d5de45c74fd..9eb4dd832cb 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -171,15 +171,24 @@ void WM_opengl_context_dispose(void *context); void WM_opengl_context_activate(void *context); void WM_opengl_context_release(void *context); -struct wmWindow *WM_window_open(struct bContext *C, const struct rcti *rect); -struct wmWindow *WM_window_open_temp(struct bContext *C, - const char *title, - int x, - int y, - int sizex, - int sizey, - int space_type, - bool dialog); +/* WM_window_open alignment */ +typedef enum WindowAlignment { + WIN_ALIGN_ABSOLUTE = 0, + WIN_ALIGN_LOCATION_CENTER, + WIN_ALIGN_PARENT_CENTER, +} WindowAlignment; + +struct wmWindow *WM_window_open(struct bContext *C, + const char *title, + int x, + int y, + int sizex, + int sizey, + int space_type, + bool dialog, + bool temp, + WindowAlignment alignment); + void WM_window_set_dpi(const wmWindow *win); bool WM_stereo3d_enabled(struct wmWindow *win, bool only_fullscreen_test); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index c4452b4c4f7..733a9b74f2c 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -462,7 +462,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) { if (WM_window_is_temp_screen(win)) { /* nothing to do for 'temp' windows, - * because WM_window_open_temp always sets window title */ + * because WM_window_open always sets window title */ } else if (win->ghostwin) { /* this is set to 1 if you don't have startup.blend open */ @@ -776,68 +776,51 @@ static bool wm_window_update_size_position(wmWindow *win) } /** - * new window, no screen yet, but we open ghostwindow for it, - * also gets the window level handlers - * \note area-rip calls this. - * \return the window or NULL. - */ -wmWindow *WM_window_open(bContext *C, const rcti *rect) -{ - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win_prev = CTX_wm_window(C); - wmWindow *win = wm_window_new(CTX_data_main(C), wm, win_prev, false); - - const float native_pixel_size = GHOST_GetNativePixelSize(win_prev->ghostwin); - - win->posx = rect->xmin / native_pixel_size; - win->posy = rect->ymin / native_pixel_size; - win->sizex = BLI_rcti_size_x(rect) / native_pixel_size; - win->sizey = BLI_rcti_size_y(rect) / native_pixel_size; - - WM_check(C); - - if (win->ghostwin) { - return win; - } - - wm_window_close(C, wm, win); - CTX_wm_window_set(C, win_prev); - return NULL; -} - -/** - * Uses `screen->temp` tag to define what to do, currently it limits - * to only one "temp" window for render out, preferences, filewindow, etc... - * * \param space_type: SPACE_VIEW3D, SPACE_INFO, ... (eSpace_Type) + * \param dialog: whether this should be made as a dialog-style window + * \param temp: whether this is considered a short-lived window + * \param alignment: how this window is positioned relative to its parent * \return the window or NULL in case of failure. */ -wmWindow *WM_window_open_temp(bContext *C, - const char *title, - int x, - int y, - int sizex, - int sizey, - int space_type, - bool dialog) +wmWindow *WM_window_open(bContext *C, + const char *title, + int x, + int y, + int sizex, + int sizey, + int space_type, + bool dialog, + bool temp, + WindowAlignment alignment) { Main *bmain = CTX_data_main(C); wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win_prev = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + rcti rect; - /* convert to native OS window coordinates */ const float native_pixel_size = GHOST_GetNativePixelSize(win_prev->ghostwin); - x /= native_pixel_size; - y /= native_pixel_size; + /* convert to native OS window coordinates */ + rect.xmin = win_prev->posx + (x / native_pixel_size); + rect.ymin = win_prev->posy + (y / native_pixel_size); sizex /= native_pixel_size; sizey /= native_pixel_size; - /* calculate position */ - rcti rect; - rect.xmin = x + win_prev->posx - sizex / 2; - rect.ymin = y + win_prev->posy - sizey / 2; + if (alignment == WIN_ALIGN_LOCATION_CENTER) { + /* Window centered around x,y location. */ + rect.xmin -= sizex / 2; + rect.ymin -= sizey / 2; + } + else if (alignment == WIN_ALIGN_PARENT_CENTER) { + /* Centered within parent. X,Y as offsets from there. */ + rect.xmin += (win_prev->sizex - sizex) / 2; + rect.ymin += (win_prev->sizey - sizey) / 2; + } + else { + /* Positioned absolutely within parent bounds. */ + } + rect.xmax = rect.xmin + sizex; rect.ymax = rect.ymin + sizey; @@ -846,22 +829,24 @@ wmWindow *WM_window_open_temp(bContext *C, /* Reuse temporary windows when they share the same title. */ wmWindow *win = NULL; - LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) { - if (WM_window_is_temp_screen(win_iter)) { - char *wintitle = GHOST_GetTitle(win_iter->ghostwin); - if (strcmp(title, wintitle) == 0) { - win = win_iter; + if (temp) { + LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) { + if (WM_window_is_temp_screen(win_iter)) { + char *wintitle = GHOST_GetTitle(win_iter->ghostwin); + if (strcmp(title, wintitle) == 0) { + win = win_iter; + } + free(wintitle); } - free(wintitle); } } /* add new window? */ if (win == NULL) { win = wm_window_new(bmain, wm, win_prev, dialog); - win->posx = rect.xmin; win->posy = rect.ymin; + *win->stereo3d_format = *win_prev->stereo3d_format; } bScreen *screen = WM_window_get_active_screen(win); @@ -889,7 +874,7 @@ wmWindow *WM_window_open_temp(bContext *C, ED_screen_scene_change(C, win, scene); } - screen->temp = 1; + screen->temp = temp; /* make window active, and validate/resize */ CTX_wm_window_set(C, win); @@ -906,10 +891,11 @@ wmWindow *WM_window_open_temp(bContext *C, */ /* ensure it shows the right spacetype editor */ - ScrArea *area = screen->areabase.first; - CTX_wm_area_set(C, area); - - ED_area_newspace(C, area, space_type, false); + if (space_type != SPACE_EMPTY) { + ScrArea *area = screen->areabase.first; + CTX_wm_area_set(C, area); + ED_area_newspace(C, area, space_type, false); + } ED_screen_change(C, screen); @@ -949,8 +935,18 @@ int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op)) int wm_window_new_exec(bContext *C, wmOperator *UNUSED(op)) { wmWindow *win_src = CTX_wm_window(C); - - bool ok = (wm_window_copy_test(C, win_src, true, true) != NULL); + ScrArea *area = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TYPE_ANY, 0); + + bool ok = (WM_window_open(C, + IFACE_("Blender"), + 0, + 0, + win_src->sizex * 0.95f, + win_src->sizey * 0.9f, + area->spacetype, + false, + false, + WIN_ALIGN_PARENT_CENTER) != NULL); return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } -- cgit v1.2.3