UI: Save Temp Window Sizes & Positions
Allow temporary windows (like File Browser, Preferences, Render, Drivers, Info) to open at their last positions and sizes. Pull Request: https://projects.blender.org/blender/blender/pulls/104727
This commit is contained in:
committed by
Harley Acheson
parent
ccd8926717
commit
91997ea89f
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 75
|
||||
#define BLENDER_FILE_SUBVERSION 76
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -1670,6 +1670,12 @@ void blo_do_versions_userdef(UserDef *userdef)
|
||||
userdef->preferences_display_type = USER_TEMP_SPACE_DISPLAY_WINDOW;
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(500, 76)) {
|
||||
if (userdef->stored_bounds.file.xmin == userdef->stored_bounds.file.xmax) {
|
||||
memcpy(&userdef->stored_bounds, &U_default.stored_bounds, sizeof(userdef->stored_bounds));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a USER_VERSION_ATLEAST check.
|
||||
|
||||
@@ -125,9 +125,7 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile);
|
||||
* \param temp_win_size: If the browser was opened in a temporary window,
|
||||
* pass its size here so we can store that in the preferences. Otherwise NULL.
|
||||
*/
|
||||
void ED_fileselect_params_to_userdef(SpaceFile *sfile,
|
||||
const int temp_win_size[2],
|
||||
bool is_maximized);
|
||||
void ED_fileselect_params_to_userdef(SpaceFile *sfile);
|
||||
|
||||
void ED_fileselect_init_layout(SpaceFile *sfile, ARegion *region);
|
||||
|
||||
|
||||
@@ -389,10 +389,9 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, short
|
||||
*/
|
||||
ScrArea *ED_screen_temp_space_open(bContext *C,
|
||||
const char *title,
|
||||
const rcti *rect_unscaled,
|
||||
eSpace_Type space_type,
|
||||
int display_type,
|
||||
bool dialog) ATTR_NONNULL(1, 3);
|
||||
bool dialog) ATTR_NONNULL(1);
|
||||
void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *arg);
|
||||
void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *arg);
|
||||
void ED_screens_region_flip_menu_create(bContext *C, uiLayout *layout, void *arg);
|
||||
|
||||
@@ -149,6 +149,16 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
|
||||
sizex = std::max(sizex, 320);
|
||||
sizey = std::max(sizey, 256);
|
||||
|
||||
WM_window_dpi_set_userdef(CTX_wm_window(C));
|
||||
rctf *stored_bounds = &U.stored_bounds.image;
|
||||
const bool bounds_valid = (stored_bounds && (BLI_rctf_size_x(stored_bounds) > 150.0f) &&
|
||||
(BLI_rctf_size_y(stored_bounds) > 100.0f));
|
||||
const bool mm_placement = WM_capabilities_flag() & WM_CAPABILITY_MULTIMONITOR_PLACEMENT;
|
||||
if (bounds_valid && mm_placement) {
|
||||
mx = int(stored_bounds->xmin * UI_SCALE_FAC);
|
||||
my = int(stored_bounds->ymin * UI_SCALE_FAC);
|
||||
}
|
||||
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ mx,
|
||||
/*xmax*/ mx + sizex,
|
||||
@@ -164,7 +174,7 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
WIN_ALIGN_LOCATION_CENTER,
|
||||
WIN_ALIGN_ABSOLUTE,
|
||||
nullptr,
|
||||
nullptr) == nullptr)
|
||||
{
|
||||
|
||||
@@ -1891,26 +1891,12 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const
|
||||
return static_cast<ScrArea *>(screen->areabase.first);
|
||||
}
|
||||
|
||||
ScrArea *ED_screen_temp_space_open(bContext *C,
|
||||
const char *title,
|
||||
const rcti *rect_unscaled,
|
||||
eSpace_Type space_type,
|
||||
int display_type,
|
||||
bool dialog)
|
||||
ScrArea *ED_screen_temp_space_open(
|
||||
bContext *C, const char *title, eSpace_Type space_type, int display_type, bool dialog)
|
||||
{
|
||||
switch (display_type) {
|
||||
case USER_TEMP_SPACE_DISPLAY_WINDOW:
|
||||
if (WM_window_open(C,
|
||||
title,
|
||||
rect_unscaled,
|
||||
int(space_type),
|
||||
false,
|
||||
dialog,
|
||||
true,
|
||||
WIN_ALIGN_LOCATION_CENTER,
|
||||
nullptr,
|
||||
nullptr))
|
||||
{
|
||||
if (WM_window_open_temp(C, title, space_type, dialog)) {
|
||||
return CTX_wm_area(C);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1541,8 +1541,11 @@ static void area_dupli_fn(bScreen * /*screen*/, ScrArea *area, void *user_data)
|
||||
/* operator callback */
|
||||
static bool area_dupli_open(bContext *C, ScrArea *area, const blender::int2 position)
|
||||
{
|
||||
const rcti window_rect = {
|
||||
position.x, position.x + area->winx, position.y, position.y + area->winy};
|
||||
const wmWindow *win = CTX_wm_window(C);
|
||||
const rcti window_rect = {win->posx + position.x,
|
||||
win->posx + position.x + area->winx,
|
||||
win->posy + position.y,
|
||||
win->posy + position.y + area->winy};
|
||||
|
||||
/* Create new window. No need to set space_type since it will be copied over. */
|
||||
wmWindow *newwin = WM_window_open(C,
|
||||
@@ -6236,12 +6239,6 @@ static void SCREEN_OT_back_to_previous(wmOperatorType *ot)
|
||||
|
||||
static wmOperatorStatus userpref_show_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
wmWindow *win_cur = CTX_wm_window(C);
|
||||
/* Use eventstate, not event from _invoke, so this can be called through exec(). */
|
||||
const wmEvent *event = win_cur->eventstate;
|
||||
int sizex = (680 + UI_NAVIGATION_REGION_WIDTH) * UI_SCALE_FAC;
|
||||
int sizey = 520 * UI_SCALE_FAC;
|
||||
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "section");
|
||||
if (prop && RNA_property_is_set(op->ptr, prop)) {
|
||||
/* Set active section via RNA, so it can fail properly. */
|
||||
@@ -6253,19 +6250,11 @@ static wmOperatorStatus userpref_show_exec(bContext *C, wmOperator *op)
|
||||
RNA_property_update(C, &pref_ptr, active_section_prop);
|
||||
}
|
||||
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ event->xy[0],
|
||||
/*xmax*/ event->xy[0] + sizex,
|
||||
/*ymin*/ event->xy[1],
|
||||
/*ymax*/ event->xy[1] + sizey,
|
||||
};
|
||||
|
||||
/* changes context! */
|
||||
if (ScrArea *area = ED_screen_temp_space_open(
|
||||
C, nullptr, &window_rect, SPACE_USERPREF, U.preferences_display_type, false))
|
||||
{
|
||||
if (WM_window_open_temp(C, nullptr, SPACE_USERPREF, false)) {
|
||||
/* The header only contains the editor switcher and looks empty.
|
||||
* So hiding in the temp window makes sense. */
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region_header = BKE_area_find_region_type(area, RGN_TYPE_HEADER);
|
||||
|
||||
region_header->flag |= RGN_FLAG_HIDDEN;
|
||||
@@ -6324,13 +6313,6 @@ static void SCREEN_OT_userpref_show(wmOperatorType *ot)
|
||||
|
||||
static wmOperatorStatus drivers_editor_show_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
wmWindow *win_cur = CTX_wm_window(C);
|
||||
/* Use eventstate, not event from _invoke, so this can be called through exec(). */
|
||||
const wmEvent *event = win_cur->eventstate;
|
||||
|
||||
int sizex = 900 * UI_SCALE_FAC;
|
||||
int sizey = 580 * UI_SCALE_FAC;
|
||||
|
||||
/* Get active property to show driver for
|
||||
* - Need to grab it first, or else this info disappears
|
||||
* after we've created the window
|
||||
@@ -6340,25 +6322,8 @@ static wmOperatorStatus drivers_editor_show_exec(bContext *C, wmOperator *op)
|
||||
PropertyRNA *prop;
|
||||
uiBut *but = UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
||||
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ event->xy[0],
|
||||
/*xmax*/ event->xy[0] + sizex,
|
||||
/*ymin*/ event->xy[1],
|
||||
/*ymax*/ event->xy[1] + sizey,
|
||||
};
|
||||
|
||||
/* changes context! */
|
||||
if (WM_window_open(C,
|
||||
IFACE_("Blender Drivers Editor"),
|
||||
&window_rect,
|
||||
SPACE_GRAPH,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
WIN_ALIGN_LOCATION_CENTER,
|
||||
nullptr,
|
||||
nullptr) != nullptr)
|
||||
{
|
||||
if (WM_window_open_temp(C, IFACE_("Blender Drivers Editor"), SPACE_GRAPH, false)) {
|
||||
ED_drivers_editor_init(C, CTX_wm_area(C));
|
||||
|
||||
/* activate driver F-Curve for the property under the cursor */
|
||||
@@ -6414,34 +6379,8 @@ static void SCREEN_OT_drivers_editor_show(wmOperatorType *ot)
|
||||
|
||||
static wmOperatorStatus info_log_show_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
wmWindow *win_cur = CTX_wm_window(C);
|
||||
/* Use eventstate, not event from _invoke, so this can be called through exec(). */
|
||||
const wmEvent *event = win_cur->eventstate;
|
||||
const int shift_y = 480;
|
||||
const int mx = event->xy[0];
|
||||
const int my = event->xy[1] + shift_y;
|
||||
int sizex = 900 * UI_SCALE_FAC;
|
||||
int sizey = 580 * UI_SCALE_FAC;
|
||||
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ mx,
|
||||
/*xmax*/ mx + sizex,
|
||||
/*ymin*/ my,
|
||||
/*ymax*/ my + sizey,
|
||||
};
|
||||
|
||||
/* changes context! */
|
||||
if (WM_window_open(C,
|
||||
IFACE_("Blender Info Log"),
|
||||
&window_rect,
|
||||
SPACE_INFO,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
WIN_ALIGN_LOCATION_CENTER,
|
||||
nullptr,
|
||||
nullptr) != nullptr)
|
||||
{
|
||||
if (WM_window_open_temp(C, IFACE_("Blender Info Log"), SPACE_INFO, false)) {
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
|
||||
|
||||
@@ -685,9 +685,7 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
|
||||
}
|
||||
}
|
||||
|
||||
void ED_fileselect_params_to_userdef(SpaceFile *sfile,
|
||||
const int temp_win_size[2],
|
||||
const bool is_maximized)
|
||||
void ED_fileselect_params_to_userdef(SpaceFile *sfile)
|
||||
{
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
UserDef_FileSpaceData *sfile_udata_new = &U.file_space_data;
|
||||
@@ -711,11 +709,6 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile,
|
||||
(params->flag & FILE_SORT_INVERT);
|
||||
}
|
||||
|
||||
if (temp_win_size && !is_maximized) {
|
||||
sfile_udata_new->temp_win_sizex = temp_win_size[0];
|
||||
sfile_udata_new->temp_win_sizey = temp_win_size[1];
|
||||
}
|
||||
|
||||
/* Tag preferences as dirty if something has changed. */
|
||||
if (memcmp(sfile_udata_new, &sfile_udata_old, sizeof(sfile_udata_old)) != 0) {
|
||||
U.runtime.is_dirty = true;
|
||||
@@ -1327,21 +1320,7 @@ void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile)
|
||||
return;
|
||||
}
|
||||
if (sfile->op) {
|
||||
wmWindow *temp_win = (wm->runtime->winactive &&
|
||||
WM_window_is_temp_screen(wm->runtime->winactive)) ?
|
||||
wm->runtime->winactive :
|
||||
nullptr;
|
||||
if (temp_win) {
|
||||
int win_size[2];
|
||||
bool is_maximized;
|
||||
|
||||
ED_fileselect_window_params_get(temp_win, win_size, &is_maximized);
|
||||
ED_fileselect_params_to_userdef(sfile, win_size, is_maximized);
|
||||
}
|
||||
else {
|
||||
ED_fileselect_params_to_userdef(sfile, nullptr, false);
|
||||
}
|
||||
|
||||
ED_fileselect_params_to_userdef(sfile);
|
||||
WM_event_fileselect_event(wm, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL);
|
||||
sfile->op = nullptr;
|
||||
}
|
||||
|
||||
@@ -2495,28 +2495,9 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
|
||||
|
||||
static wmOperatorStatus outliner_orphans_manage_invoke(bContext *C,
|
||||
wmOperator * /*op*/,
|
||||
const wmEvent *event)
|
||||
const wmEvent * /*event*/)
|
||||
{
|
||||
const int sizex = int(450.0f * UI_SCALE_FAC);
|
||||
const int sizey = int(450.0f * UI_SCALE_FAC);
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ event->xy[0],
|
||||
/*xmax*/ event->xy[0] + sizex,
|
||||
/*ymin*/ event->xy[1],
|
||||
/*ymax*/ event->xy[1] + sizey,
|
||||
};
|
||||
|
||||
if (WM_window_open(C,
|
||||
IFACE_("Manage Unused Data"),
|
||||
&window_rect,
|
||||
SPACE_OUTLINER,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
WIN_ALIGN_LOCATION_CENTER,
|
||||
nullptr,
|
||||
nullptr) != nullptr)
|
||||
{
|
||||
if (WM_window_open_temp(C, IFACE_("Manage Unused Data"), SPACE_OUTLINER, false)) {
|
||||
SpaceOutliner *soutline = CTX_wm_space_outliner(C);
|
||||
soutline->outlinevis = SO_ID_ORPHANS;
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_rect.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_colorband_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
@@ -194,12 +196,17 @@ typedef struct UserDef_FileSpaceData {
|
||||
int flag; /* FileSelectParams.flag */
|
||||
int _pad0;
|
||||
uint64_t filter_id; /* FileSelectParams.filter_id */
|
||||
|
||||
/** Info used when creating the file browser in a temporary window. */
|
||||
int temp_win_sizex;
|
||||
int temp_win_sizey;
|
||||
} UserDef_FileSpaceData;
|
||||
|
||||
typedef struct UserDef_TempWinBounds {
|
||||
rctf file;
|
||||
rctf userpref;
|
||||
rctf image;
|
||||
rctf graph;
|
||||
rctf info;
|
||||
rctf outliner;
|
||||
} UserDef_TempWinBounds;
|
||||
|
||||
/**
|
||||
* Checking experimental members must use the #USER_EXPERIMENTAL_TEST() macro
|
||||
* unless the #USER_DEVELOPER_UI is known to be enabled.
|
||||
@@ -614,6 +621,8 @@ typedef struct UserDef {
|
||||
UserDef_SpaceData space_data;
|
||||
UserDef_FileSpaceData file_space_data;
|
||||
|
||||
UserDef_TempWinBounds stored_bounds;
|
||||
|
||||
UserDef_Experimental experimental;
|
||||
|
||||
/** Runtime data (keep last). */
|
||||
|
||||
@@ -207,6 +207,8 @@ enum eWM_CapabilitiesFlag {
|
||||
WM_CAPABILITY_CURSOR_RGBA = (1 << 10),
|
||||
/** Support on demand cursor generation. */
|
||||
WM_CAPABILITY_CURSOR_GENERATOR = (1 << 11),
|
||||
/** Ability to save/restore windows among multiple monitors. */
|
||||
WM_CAPABILITY_MULTIMONITOR_PLACEMENT = (1 << 12),
|
||||
/** The initial value, indicates the value needs to be set by inspecting GHOST. */
|
||||
WM_CAPABILITY_INITIALIZED = (1u << 31),
|
||||
};
|
||||
@@ -398,6 +400,8 @@ wmWindow *WM_window_open(bContext *C,
|
||||
void (*area_setup_fn)(bScreen *screen, ScrArea *area, void *user_data),
|
||||
void *area_setup_user_data) ATTR_NONNULL(1, 3);
|
||||
|
||||
wmWindow *WM_window_open_temp(bContext *C, const char *title, int space_type, bool dialog);
|
||||
|
||||
void WM_window_dpi_set_userdef(const wmWindow *win);
|
||||
/**
|
||||
* Return the windows DPI as a scale, bypassing UI scale preference.
|
||||
|
||||
@@ -2817,43 +2817,26 @@ static eHandlerActionFlag wm_handler_fileselect_do(bContext *C,
|
||||
|
||||
switch (val) {
|
||||
case EVT_FILESELECT_FULL_OPEN: {
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
const blender::int2 window_size = WM_window_native_pixel_size(win);
|
||||
const blender::int2 window_center = window_size / 2;
|
||||
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ window_center[0],
|
||||
/*xmax*/ window_center[0] + int(U.file_space_data.temp_win_sizex * UI_SCALE_FAC),
|
||||
/*ymin*/ window_center[1],
|
||||
/*ymax*/ window_center[1] + int(U.file_space_data.temp_win_sizey * UI_SCALE_FAC),
|
||||
};
|
||||
|
||||
if (ScrArea *area = ED_screen_temp_space_open(C,
|
||||
IFACE_("Blender File View"),
|
||||
&window_rect,
|
||||
SPACE_FILE,
|
||||
U.filebrowser_display_type,
|
||||
true))
|
||||
{
|
||||
ARegion *region_header = BKE_area_find_region_type(area, RGN_TYPE_HEADER);
|
||||
|
||||
BLI_assert(area->spacetype == SPACE_FILE);
|
||||
|
||||
region_header->flag |= RGN_FLAG_HIDDEN;
|
||||
/* Header on bottom, #AZone triangle to toggle header looks misplaced at the top. */
|
||||
region_header->alignment = RGN_ALIGN_BOTTOM;
|
||||
|
||||
/* Settings for file-browser, #sfile is not operator owner but sends events. */
|
||||
SpaceFile *sfile = (SpaceFile *)area->spacedata.first;
|
||||
sfile->op = handler->op;
|
||||
|
||||
ED_fileselect_set_params_from_userdef(sfile);
|
||||
}
|
||||
else {
|
||||
BKE_report(&wm->runtime->reports, RPT_ERROR, "Failed to open window!");
|
||||
ScrArea *area = ED_screen_temp_space_open(
|
||||
C, IFACE_("Blender File View"), SPACE_FILE, U.filebrowser_display_type, true);
|
||||
if (!area) {
|
||||
BKE_report(&wm->runtime->reports, RPT_ERROR, "Failed to open file browser!");
|
||||
return WM_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
ARegion *region_header = BKE_area_find_region_type(area, RGN_TYPE_HEADER);
|
||||
BLI_assert(area->spacetype == SPACE_FILE);
|
||||
|
||||
region_header->flag |= RGN_FLAG_HIDDEN;
|
||||
/* Header on bottom, #AZone triangle to toggle header looks misplaced at the top. */
|
||||
region_header->alignment = RGN_ALIGN_BOTTOM;
|
||||
|
||||
/* Settings for file-browser, #sfile is not operator owner but sends events. */
|
||||
SpaceFile *sfile = (SpaceFile *)area->spacedata.first;
|
||||
sfile->op = handler->op;
|
||||
|
||||
ED_fileselect_set_params_from_userdef(sfile);
|
||||
|
||||
action = WM_HANDLER_BREAK;
|
||||
break;
|
||||
}
|
||||
@@ -2894,11 +2877,7 @@ static eHandlerActionFlag wm_handler_fileselect_do(bContext *C,
|
||||
continue;
|
||||
}
|
||||
|
||||
int win_size[2];
|
||||
bool is_maximized;
|
||||
ED_fileselect_window_params_get(win, win_size, &is_maximized);
|
||||
ED_fileselect_params_to_userdef(
|
||||
static_cast<SpaceFile *>(file_area->spacedata.first), win_size, is_maximized);
|
||||
ED_fileselect_params_to_userdef(static_cast<SpaceFile *>(file_area->spacedata.first));
|
||||
|
||||
if (BLI_listbase_is_single(&file_area->spacedata)) {
|
||||
BLI_assert(root_win != win);
|
||||
@@ -2930,8 +2909,7 @@ static eHandlerActionFlag wm_handler_fileselect_do(bContext *C,
|
||||
}
|
||||
|
||||
if (!temp_win && ctx_area->full) {
|
||||
ED_fileselect_params_to_userdef(
|
||||
static_cast<SpaceFile *>(ctx_area->spacedata.first), nullptr, false);
|
||||
ED_fileselect_params_to_userdef(static_cast<SpaceFile *>(ctx_area->spacedata.first));
|
||||
ED_screen_full_prevspace(C, ctx_area);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,8 +447,51 @@ void wm_quit_with_optional_confirmation_prompt(bContext *C, wmWindow *win)
|
||||
/** \name Window Close
|
||||
* \{ */
|
||||
|
||||
static rctf *stored_window_bounds(eSpace_Type space_type)
|
||||
{
|
||||
if (space_type == SPACE_IMAGE) {
|
||||
return &U.stored_bounds.image;
|
||||
}
|
||||
if (space_type == SPACE_USERPREF) {
|
||||
return &U.stored_bounds.userpref;
|
||||
}
|
||||
if (space_type == SPACE_GRAPH) {
|
||||
return &U.stored_bounds.graph;
|
||||
}
|
||||
if (space_type == SPACE_INFO) {
|
||||
return &U.stored_bounds.info;
|
||||
}
|
||||
if (space_type == SPACE_OUTLINER) {
|
||||
return &U.stored_bounds.outliner;
|
||||
}
|
||||
if (space_type == SPACE_FILE) {
|
||||
return &U.stored_bounds.file;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
|
||||
{
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
|
||||
if (screen->temp && BLI_listbase_is_single(&screen->areabase) && !WM_window_is_maximized(win)) {
|
||||
ScrArea *area = static_cast<ScrArea *>(screen->areabase.first);
|
||||
rctf *stored_bounds = stored_window_bounds(eSpace_Type(area->spacetype));
|
||||
|
||||
if (stored_bounds) {
|
||||
/* Get DPI and scale from parent window, if there is one. */
|
||||
WM_window_dpi_set_userdef(win->parent ? win->parent : win);
|
||||
const float f = GHOST_GetNativePixelSize(static_cast<GHOST_WindowHandle>(win->ghostwin));
|
||||
stored_bounds->xmin = float(win->posx) * f / UI_SCALE_FAC;
|
||||
stored_bounds->xmax = stored_bounds->xmin + float(win->sizex) * f / UI_SCALE_FAC;
|
||||
stored_bounds->ymin = float(win->posy) * f / UI_SCALE_FAC;
|
||||
stored_bounds->ymax = stored_bounds->ymin + float(win->sizey) * f / UI_SCALE_FAC;
|
||||
/* Tag user preferences as dirty. */
|
||||
U.runtime.is_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
wmWindow *win_other;
|
||||
|
||||
/* First check if there is another main window remaining. */
|
||||
@@ -472,7 +515,6 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
|
||||
}
|
||||
}
|
||||
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
WorkSpace *workspace = WM_window_get_active_workspace(win);
|
||||
WorkSpaceLayout *layout = BKE_workspace_active_layout_get(win->workspace_hook);
|
||||
|
||||
@@ -1148,23 +1190,23 @@ wmWindow *WM_window_open(bContext *C,
|
||||
const float native_pixel_size = GHOST_GetNativePixelSize(
|
||||
static_cast<GHOST_WindowHandle>(win_prev->ghostwin));
|
||||
/* Convert to native OS window coordinates. */
|
||||
rect.xmin = win_prev->posx + (x / native_pixel_size);
|
||||
rect.ymin = win_prev->posy + (y / native_pixel_size);
|
||||
rect.xmin = x / native_pixel_size;
|
||||
rect.ymin = y / native_pixel_size;
|
||||
sizex /= native_pixel_size;
|
||||
sizey /= native_pixel_size;
|
||||
|
||||
if (alignment == WIN_ALIGN_LOCATION_CENTER) {
|
||||
/* Window centered around x,y location. */
|
||||
rect.xmin -= sizex / 2;
|
||||
rect.ymin -= sizey / 2;
|
||||
rect.xmin += win_prev->posx - (sizex / 2);
|
||||
rect.ymin += win_prev->posy - (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;
|
||||
rect.xmin += win_prev->posx + ((win_prev->sizex - sizex) / 2);
|
||||
rect.ymin += win_prev->posy + ((win_prev->sizey - sizey) / 2);
|
||||
}
|
||||
else {
|
||||
/* Positioned absolutely within parent bounds. */
|
||||
else if (alignment == WIN_ALIGN_ABSOLUTE) {
|
||||
/* Positioned absolutely in desktop coordinates. */
|
||||
}
|
||||
|
||||
rect.xmax = rect.xmin + sizex;
|
||||
@@ -1282,6 +1324,43 @@ wmWindow *WM_window_open(bContext *C,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wmWindow *WM_window_open_temp(bContext *C, const char *title, int space_type, bool dialog)
|
||||
{
|
||||
rcti rect;
|
||||
WM_window_dpi_set_userdef(CTX_wm_window(C));
|
||||
eWindowAlignment align;
|
||||
rctf *stored_bounds = stored_window_bounds(eSpace_Type(space_type));
|
||||
const bool bounds_valid = (stored_bounds && (BLI_rctf_size_x(stored_bounds) > 150.0f) &&
|
||||
(BLI_rctf_size_y(stored_bounds) > 100.0f));
|
||||
const bool mm_placement = WM_capabilities_flag() & WM_CAPABILITY_MULTIMONITOR_PLACEMENT;
|
||||
|
||||
if (bounds_valid && mm_placement) {
|
||||
rect.xmin = (int)(stored_bounds->xmin * UI_SCALE_FAC);
|
||||
rect.ymin = (int)(stored_bounds->ymin * UI_SCALE_FAC);
|
||||
rect.xmax = (int)(stored_bounds->xmax * UI_SCALE_FAC);
|
||||
rect.ymax = (int)(stored_bounds->ymax * UI_SCALE_FAC);
|
||||
align = WIN_ALIGN_ABSOLUTE;
|
||||
}
|
||||
else {
|
||||
wmWindow *win_cur = CTX_wm_window(C);
|
||||
const int width = int((bounds_valid ? BLI_rctf_size_x(stored_bounds) : 800.0f) * UI_SCALE_FAC);
|
||||
const int height = int((bounds_valid ? BLI_rctf_size_y(stored_bounds) : 600.0f) *
|
||||
UI_SCALE_FAC);
|
||||
/* Use eventstate, not event from _invoke, so this can be called through exec(). */
|
||||
const wmEvent *event = win_cur->eventstate;
|
||||
rect.xmin = event->xy[0];
|
||||
rect.ymin = event->xy[1];
|
||||
rect.xmax = event->xy[0] + width;
|
||||
rect.ymax = event->xy[1] + height;
|
||||
align = WIN_ALIGN_LOCATION_CENTER;
|
||||
}
|
||||
|
||||
wmWindow *win = WM_window_open(
|
||||
C, title, &rect, space_type, false, dialog, true, align, nullptr, nullptr);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -2242,6 +2321,9 @@ eWM_CapabilitiesFlag WM_capabilities_flag()
|
||||
if (ghost_flag & GHOST_kCapabilityCursorGenerator) {
|
||||
flag |= WM_CAPABILITY_CURSOR_GENERATOR;
|
||||
}
|
||||
if (ghost_flag & GHOST_kCapabilityMultiMonitorPlacement) {
|
||||
flag |= WM_CAPABILITY_MULTIMONITOR_PLACEMENT;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user