WIP: UI: Save Temp Window Sizes & Positions #104727
|
@ -213,17 +213,27 @@ const UserDef U_default = {
|
|||
.section_active = USER_SECTION_INTERFACE,
|
||||
},
|
||||
|
||||
.file_space_data =
|
||||
{
|
||||
.display_type = FILE_VERTICALDISPLAY,
|
||||
.thumbnail_size = 96,
|
||||
.sort_type = FILE_SORT_ALPHA,
|
||||
.details_flags = FILE_DETAILS_SIZE | FILE_DETAILS_DATETIME,
|
||||
.flag = FILE_HIDE_DOT,
|
||||
.filter_id = FILTER_ID_ALL,
|
||||
.file_space_data = {.display_type = FILE_VERTICALDISPLAY,
|
||||
.thumbnail_size = 96,
|
||||
.sort_type = FILE_SORT_ALPHA,
|
||||
.details_flags = FILE_DETAILS_SIZE | FILE_DETAILS_DATETIME,
|
||||
.flag = FILE_HIDE_DOT,
|
||||
.filter_id = FILTER_ID_ALL},
|
||||
|
||||
.temp_win_sizex = 1060,
|
||||
.temp_win_sizey = 600,
|
||||
.file_winstate =
|
||||
{
|
||||
.posx = 0,
|
||||
.posy = 0,
|
||||
.sizex = 1060,
|
||||
.sizey = 600,
|
||||
},
|
||||
|
||||
.file_winstate =
|
||||
{
|
||||
.posx = 0,
|
||||
.posy = 0,
|
||||
.sizex = 560,
|
||||
.sizey = 520,
|
||||
},
|
||||
|
||||
.sequencer_disk_cache_dir = "",
|
||||
|
|
|
@ -108,9 +108,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);
|
||||
|
||||
|
@ -170,8 +168,6 @@ void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, bool deferred)
|
|||
void ED_fileselect_deselect_all(SpaceFile *sfile);
|
||||
void ED_fileselect_activate_by_relpath(SpaceFile *sfile, const char *relative_path);
|
||||
|
||||
void ED_fileselect_window_params_get(const wmWindow *win, int r_win_size[2], bool *r_is_maximized);
|
||||
|
||||
/**
|
||||
* Return the File Browser area in which \a file_operator is active.
|
||||
*/
|
||||
|
|
|
@ -1459,11 +1459,12 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
area = sad->sa1;
|
||||
}
|
||||
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
const rcti window_rect = {
|
||||
/*xmin*/ area->totrct.xmin,
|
||||
/*xmax*/ area->totrct.xmin + area->winx,
|
||||
/*ymin*/ area->totrct.ymin,
|
||||
/*ymax*/ area->totrct.ymin + area->winy,
|
||||
/*xmin*/ win->posx + area->totrct.xmin,
|
||||
/*xmax*/ win->posx + area->totrct.xmin + area->winx,
|
||||
/*ymin*/ win->posy + area->totrct.ymin,
|
||||
/*ymax*/ win->posy + area->totrct.ymin + area->winy,
|
||||
};
|
||||
|
||||
/* Create new window. No need to set space_type since it will be copied over. */
|
||||
|
@ -5200,12 +5201,6 @@ static void SCREEN_OT_back_to_previous(wmOperatorType *ot)
|
|||
|
||||
static int 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 = (500 + 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. */
|
||||
|
@ -5217,24 +5212,14 @@ static int 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 (WM_window_open(C,
|
||||
IFACE_("Blender Preferences"),
|
||||
&window_rect,
|
||||
SPACE_USERPREF,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
WIN_ALIGN_LOCATION_CENTER,
|
||||
nullptr,
|
||||
nullptr) != nullptr)
|
||||
if (WM_window_open_temp(C,
|
||||
IFACE_("Blender Preferences"),
|
||||
&U.preferences_winstate,
|
||||
500 + UI_NAVIGATION_REGION_WIDTH,
|
||||
520,
|
||||
SPACE_USERPREF,
|
||||
false) != nullptr)
|
||||
{
|
||||
/* The header only contains the editor switcher and looks empty.
|
||||
* So hiding in the temp window makes sense. */
|
||||
|
|
|
@ -623,17 +623,6 @@ void ED_fileselect_deselect_all(SpaceFile *sfile)
|
|||
* may also be remembered, but only conditionally. */
|
||||
#define PARAMS_FLAGS_REMEMBERED (FILE_HIDE_DOT)
|
||||
|
||||
void ED_fileselect_window_params_get(const wmWindow *win, int r_win_size[2], bool *r_is_maximized)
|
||||
{
|
||||
/* Get DPI/pixel-size independent size to be stored in preferences. */
|
||||
WM_window_set_dpi(win); /* Ensure the DPI is taken from the right window. */
|
||||
|
||||
r_win_size[0] = WM_window_pixels_x(win) / UI_SCALE_FAC;
|
||||
r_win_size[1] = WM_window_pixels_y(win) / UI_SCALE_FAC;
|
||||
|
||||
*r_is_maximized = WM_window_is_maximized(win);
|
||||
}
|
||||
|
||||
static bool file_select_use_default_display_type(const SpaceFile *sfile)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
@ -680,9 +669,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;
|
||||
|
@ -706,11 +693,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;
|
||||
|
@ -1302,17 +1284,7 @@ void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile)
|
|||
wmWindow *temp_win = (wm->winactive && WM_window_is_temp_screen(wm->winactive)) ?
|
||||
wm->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;
|
||||
}
|
||||
|
|
|
@ -684,12 +684,19 @@ 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;
|
||||
|
||||
/**
|
||||
* Storage for temp window position and size. Needs to
|
||||
* use floats (divided by UI_DPI_FAC) to avoid drifting.
|
||||
*/
|
||||
typedef struct UserDef_WinState {
|
||||
float posx;
|
||||
float posy;
|
||||
float sizex;
|
||||
float sizey;
|
||||
} UserDef_WinState;
|
||||
|
||||
typedef struct UserDef_Experimental {
|
||||
/* Debug options, always available. */
|
||||
char use_undo_legacy;
|
||||
|
@ -1040,6 +1047,9 @@ typedef struct UserDef {
|
|||
UserDef_SpaceData space_data;
|
||||
UserDef_FileSpaceData file_space_data;
|
||||
|
||||
UserDef_WinState file_winstate;
|
||||
UserDef_WinState preferences_winstate;
|
||||
|
||||
UserDef_Experimental experimental;
|
||||
|
||||
/** Runtime data (keep last). */
|
||||
|
@ -1478,7 +1488,8 @@ typedef enum eUserpref_RenderDisplayType {
|
|||
USER_RENDER_DISPLAY_NONE = 0,
|
||||
USER_RENDER_DISPLAY_SCREEN = 1,
|
||||
USER_RENDER_DISPLAY_AREA = 2,
|
||||
USER_RENDER_DISPLAY_WINDOW = 3
|
||||
USER_RENDER_DISPLAY_WINDOW = 3,
|
||||
USER_RENDER_DISPLAY_WINDOW_SAVED = 4
|
||||
} eUserpref_RenderDisplayType;
|
||||
|
||||
typedef enum eUserpref_TempSpaceDisplayType {
|
||||
|
|
|
@ -392,6 +392,11 @@ typedef struct wmWindow {
|
|||
/** Private runtime info to show text in the status bar. */
|
||||
void *cursor_keymap_status;
|
||||
|
||||
/* Optional pointer to a UserDef_WinState used to save/restore size and position. */
|
||||
struct UserDef_WinState *savestate;
|
||||
|
||||
void *_pad2;
|
||||
|
||||
/**
|
||||
* The time when the key is pressed in milliseconds (see #GHOST_GetEventTime).
|
||||
* Used to detect double-click events.
|
||||
|
|
|
@ -462,6 +462,8 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
|
|||
SDNA_DEFAULT_DECL(bTheme),
|
||||
SDNA_DEFAULT_DECL_EX(UserDef_SpaceData, UserDef.space_data),
|
||||
SDNA_DEFAULT_DECL_EX(UserDef_FileSpaceData, UserDef.file_space_data),
|
||||
SDNA_DEFAULT_DECL_EX(UserDef_WinState, UserDef.file_winstate),
|
||||
SDNA_DEFAULT_DECL_EX(UserDef_WinState, UserDef.preferences_winstate),
|
||||
SDNA_DEFAULT_DECL_EX(WalkNavigation, UserDef.walk_navigation),
|
||||
SDNA_DEFAULT_DECL(bUserAssetLibrary),
|
||||
SDNA_DEFAULT_DECL(bUserExtensionRepo),
|
||||
|
|
|
@ -349,6 +349,14 @@ 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, 2, 3);
|
||||
|
||||
struct wmWindow *WM_window_open_temp(struct bContext *C,
|
||||
const char *title,
|
||||
struct UserDef_WinState *state,
|
||||
int def_sizex,
|
||||
int def_sizey,
|
||||
int space_type,
|
||||
bool dialog);
|
||||
|
||||
void WM_window_set_dpi(const wmWindow *win);
|
||||
|
||||
bool WM_stereo3d_enabled(wmWindow *win, bool only_fullscreen_test);
|
||||
|
|
|
@ -2659,26 +2659,11 @@ static eHandlerActionFlag wm_handler_fileselect_do(bContext *C,
|
|||
|
||||
switch (val) {
|
||||
case EVT_FILESELECT_FULL_OPEN: {
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
const int window_center[2] = {
|
||||
WM_window_pixels_x(win) / 2,
|
||||
WM_window_pixels_y(win) / 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))
|
||||
if (WM_window_open_temp(
|
||||
C, IFACE_("Blender File View"), &U.file_winstate, 1060, 600, SPACE_FILE, true) !=
|
||||
nullptr)
|
||||
{
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region_header = BKE_area_find_region_type(area, RGN_TYPE_HEADER);
|
||||
|
||||
BLI_assert(area->spacetype == SPACE_FILE);
|
||||
|
@ -2738,11 +2723,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);
|
||||
|
@ -2774,8 +2755,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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -428,6 +428,27 @@ void wm_quit_with_optional_confirmation_prompt(bContext *C, wmWindow *win)
|
|||
|
||||
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
|
||||
{
|
||||
if (win->savestate && !WM_window_is_maximized(win)) {
|
||||
/* Get DPI and scale from parent window, if there is one. */
|
||||
WM_window_set_dpi(win->parent ? win->parent : win);
|
||||
float f = GHOST_GetNativePixelSize(static_cast<GHOST_WindowHandle>(win->ghostwin));
|
||||
float sizex = (float)win->sizex * f / UI_SCALE_FAC;
|
||||
float sizey = (float)win->sizey * f / UI_SCALE_FAC;
|
||||
float posx = (float)win->posx * f / UI_SCALE_FAC;
|
||||
float posy = (float)win->posy * f / UI_SCALE_FAC;
|
||||
|
||||
if (sizex != win->savestate->sizex || sizey != win->savestate->sizey ||
|
||||
posx != win->savestate->posx || posy != win->savestate->posy)
|
||||
{
|
||||
win->savestate->sizex = sizex;
|
||||
win->savestate->sizey = sizey;
|
||||
win->savestate->posx = posx;
|
||||
win->savestate->posy = posy;
|
||||
/* Tag user preferences as dirty. */
|
||||
U.runtime.is_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
wmWindow *win_other;
|
||||
|
||||
/* First check if there is another main window remaining. */
|
||||
|
@ -960,23 +981,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;
|
||||
|
@ -1094,6 +1115,44 @@ wmWindow *WM_window_open(bContext *C,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
wmWindow *WM_window_open_temp(struct bContext *C,
|
||||
const char *title,
|
||||
UserDef_WinState *state,
|
||||
int def_sizex,
|
||||
int def_sizey,
|
||||
int space_type,
|
||||
bool dialog)
|
||||
{
|
||||
rcti rect;
|
||||
|
||||
int posx, posy, sizex, sizey;
|
||||
eWindowAlignment align;
|
||||
|
||||
WM_window_set_dpi(CTX_wm_window(C));
|
||||
|
||||
if (state && state->sizex != 0.0f) {
|
||||
rect.xmin = (int)(state->posx * UI_SCALE_FAC);
|
||||
rect.ymin = (int)(state->posy * UI_SCALE_FAC);
|
||||
rect.xmax = rect.xmin + (int)(state->sizex * UI_SCALE_FAC);
|
||||
rect.ymax = rect.ymin + (int)(state->sizey * UI_SCALE_FAC);
|
||||
align = WIN_ALIGN_ABSOLUTE;
|
||||
}
|
||||
else {
|
||||
rect.xmin = 0;
|
||||
rect.ymin = 0;
|
||||
rect.xmax = def_sizex * UI_SCALE_FAC;
|
||||
rect.ymax = def_sizey * UI_SCALE_FAC;
|
||||
align = WIN_ALIGN_LOCATION_CENTER;
|
||||
}
|
||||
|
||||
wmWindow *win = WM_window_open(
|
||||
C, title, &rect, space_type, false, dialog, true, align, nullptr, nullptr);
|
||||
|
||||
win->savestate = state;
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
Loading…
Reference in New Issue