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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
ScrArea *area = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TYPE_ANY, 0);
|
||||
|
||||
bool ok = (wm_window_copy_test(C, win_src, true, true) != NULL);
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user