Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_event_system.c
| Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_workspace.h" | #include "BKE_workspace.h" | ||||
| #include "BKE_sound.h" | #include "BKE_sound.h" | ||||
| #include "BLT_translation.h" | |||||
| #include "ED_fileselect.h" | #include "ED_fileselect.h" | ||||
| #include "ED_info.h" | #include "ED_info.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "ED_util.h" | #include "ED_util.h" | ||||
| #include "ED_undo.h" | #include "ED_undo.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| ▲ Show 20 Lines • Show All 2,270 Lines • ▼ Show 20 Lines | static int wm_handler_fileselect_do(bContext *C, | ||||
| SpaceFile *sfile; | SpaceFile *sfile; | ||||
| int action = WM_HANDLER_CONTINUE; | int action = WM_HANDLER_CONTINUE; | ||||
| switch (val) { | switch (val) { | ||||
| case EVT_FILESELECT_FULL_OPEN: { | case EVT_FILESELECT_FULL_OPEN: { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| const int sizex = 1020 * UI_DPI_FAC; | const int sizex = 1020 * UI_DPI_FAC; | ||||
| const int sizey = 600 * UI_DPI_FAC; | const int sizey = 600 * UI_DPI_FAC; | ||||
| ScrArea *area; | |||||
| if (WM_window_open_temp(C, | if ((area = ED_screen_temp_space_open(C, | ||||
| IFACE_("Blender File View"), | |||||
| WM_window_pixels_x(win) / 2, | WM_window_pixels_x(win) / 2, | ||||
| WM_window_pixels_y(win) / 2, | WM_window_pixels_y(win) / 2, | ||||
| sizex, | sizex, | ||||
| sizey, | sizey, | ||||
| WM_WINDOW_FILESEL) != NULL) { | SPACE_FILE, | ||||
| ScrArea *area = CTX_wm_area(C); | U.filebrowser_display_type))) { | ||||
| ARegion *region_header = BKE_area_find_region_type(area, RGN_TYPE_HEADER); | ARegion *region_header = BKE_area_find_region_type(area, RGN_TYPE_HEADER); | ||||
| BLI_assert(area->spacetype == SPACE_FILE); | BLI_assert(area->spacetype == SPACE_FILE); | ||||
| region_header->flag |= RGN_FLAG_HIDDEN; | region_header->flag |= RGN_FLAG_HIDDEN; | ||||
| /* Header on bottom, AZone triangle to toggle header looks misplaced at the top */ | /* Header on bottom, AZone triangle to toggle header looks misplaced at the top */ | ||||
| region_header->alignment = RGN_ALIGN_BOTTOM; | region_header->alignment = RGN_ALIGN_BOTTOM; | ||||
| Show All 22 Lines | case EVT_FILESELECT_EXTERNAL_CANCEL: { | ||||
| if (val == EVT_FILESELECT_EXTERNAL_CANCEL) { | if (val == EVT_FILESELECT_EXTERNAL_CANCEL) { | ||||
| /* The window might have been freed already. */ | /* The window might have been freed already. */ | ||||
| if (BLI_findindex(&wm->windows, handler->context.win) == -1) { | if (BLI_findindex(&wm->windows, handler->context.win) == -1) { | ||||
| handler->context.win = NULL; | handler->context.win = NULL; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| for (wmWindow *win = wm->windows.first; win; win = win->next) { | wmWindow *temp_win; | ||||
| if (WM_window_is_temp_screen(win)) { | ScrArea *ctx_sa = CTX_wm_area(C); | ||||
| bScreen *screen = WM_window_get_active_screen(win); | |||||
| ScrArea *file_sa = screen->areabase.first; | |||||
| BLI_assert(file_sa->spacetype == SPACE_FILE); | for (temp_win = wm->windows.first; temp_win; temp_win = temp_win->next) { | ||||
| bScreen *screen = WM_window_get_active_screen(temp_win); | |||||
| ScrArea *file_sa = screen->areabase.first; | |||||
| if (screen->temp && (file_sa->spacetype == SPACE_FILE)) { | |||||
| if (BLI_listbase_is_single(&file_sa->spacedata)) { | if (BLI_listbase_is_single(&file_sa->spacedata)) { | ||||
| BLI_assert(ctx_win != win); | BLI_assert(ctx_win != temp_win); | ||||
| wm_window_close(C, wm, win); | wm_window_close(C, wm, temp_win); | ||||
| CTX_wm_window_set(C, ctx_win); // wm_window_close() NULLs. | CTX_wm_window_set(C, ctx_win); // wm_window_close() NULLs. | ||||
| /* Some operators expect a drawable context (for EVT_FILESELECT_EXEC) */ | /* Some operators expect a drawable context (for EVT_FILESELECT_EXEC) */ | ||||
| wm_window_make_drawable(wm, ctx_win); | wm_window_make_drawable(wm, ctx_win); | ||||
| /* Ensure correct cursor position, otherwise, popups may close immediately after | /* Ensure correct cursor position, otherwise, popups may close immediately after | ||||
| * opening (UI_BLOCK_MOVEMOUSE_QUIT) */ | * opening (UI_BLOCK_MOVEMOUSE_QUIT) */ | ||||
| wm_get_cursor_position(ctx_win, &ctx_win->eventstate->x, &ctx_win->eventstate->y); | wm_get_cursor_position(ctx_win, &ctx_win->eventstate->x, &ctx_win->eventstate->y); | ||||
| wm->winactive = ctx_win; /* Reports use this... */ | wm->winactive = ctx_win; /* Reports use this... */ | ||||
| if (handler->context.win == win) { | if (handler->context.win == temp_win) { | ||||
| handler->context.win = NULL; | handler->context.win = NULL; | ||||
| } | } | ||||
| } | } | ||||
| else if (file_sa->full) { | else if (file_sa->full) { | ||||
| ED_screen_full_prevspace(C, file_sa); | ED_screen_full_prevspace(C, file_sa); | ||||
| } | } | ||||
| else { | else { | ||||
| ED_area_prevspace(C, file_sa); | ED_area_prevspace(C, file_sa); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (!temp_win && ctx_sa->full) { | |||||
| ED_screen_full_prevspace(C, ctx_sa); | |||||
| } | |||||
| } | } | ||||
Severin: Maybe this closing logic should be moved into a `ED_screen_temp_space_close()`, although I'm a… | |||||
| wm_handler_op_context(C, handler, ctx_win->eventstate); | wm_handler_op_context(C, handler, ctx_win->eventstate); | ||||
| /* needed for UI_popup_menu_reports */ | /* needed for UI_popup_menu_reports */ | ||||
| if (val == EVT_FILESELECT_EXEC) { | if (val == EVT_FILESELECT_EXEC) { | ||||
| int retval; | int retval; | ||||
| ▲ Show 20 Lines • Show All 1,096 Lines • ▼ Show 20 Lines | |||||
| * The file window can send event to make it execute, thus ensuring | * The file window can send event to make it execute, thus ensuring | ||||
| * executing happens outside of lower level queues, with UI refreshed. | * executing happens outside of lower level queues, with UI refreshed. | ||||
| * Should also allow multiwin solutions | * Should also allow multiwin solutions | ||||
| */ | */ | ||||
| void WM_event_add_fileselect(bContext *C, wmOperator *op) | void WM_event_add_fileselect(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| const bool is_temp_screen = WM_window_is_temp_screen(win); | |||||
| /* Don't add the file handler to the temporary window, or else it owns the handlers for itself, | /* Don't add the file handler to the temporary window, or else it owns the handlers for itself, | ||||
| * causing dangling pointers once it's destructed through a handler. It has a parent which should | * causing dangling pointers once it's destructed through a handler. It has a parent which should | ||||
| * hold the handlers itself. */ | * hold the handlers itself. */ | ||||
| ListBase *modalhandlers = WM_window_is_temp_screen(win) ? &win->parent->modalhandlers : | ListBase *modalhandlers = is_temp_screen ? &win->parent->modalhandlers : &win->modalhandlers; | ||||
| &win->modalhandlers; | |||||
| /* Close any popups, like when opening a file browser from the splash. */ | /* Close any popups, like when opening a file browser from the splash. */ | ||||
| UI_popup_handlers_remove_all(C, modalhandlers); | UI_popup_handlers_remove_all(C, modalhandlers); | ||||
| if (!is_temp_screen) { | |||||
| /* only allow 1 file selector open per window */ | |||||
| LISTBASE_FOREACH_MUTABLE (wmEventHandler *, handler_base, modalhandlers) { | |||||
| if (handler_base->type == WM_HANDLER_TYPE_OP) { | |||||
| wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base; | |||||
| if (handler->is_fileselect == false) { | |||||
| continue; | |||||
| } | |||||
| bScreen *screen = CTX_wm_screen(C); | |||||
| bool cancel_handler = true; | |||||
| /* find the area with the file selector for this handler */ | |||||
| ED_screen_areas_iter(win, screen, sa) | |||||
| { | |||||
| if (sa->spacetype == SPACE_FILE) { | |||||
| SpaceFile *sfile = sa->spacedata.first; | |||||
| if (sfile->op == handler->op) { | |||||
| CTX_wm_area_set(C, sa); | |||||
| wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_CANCEL); | |||||
| cancel_handler = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* if not found we stop the handler without changing the screen */ | |||||
| if (cancel_handler) { | |||||
| wm_handler_fileselect_do( | |||||
| C, &win->modalhandlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| wmEventHandler_Op *handler = MEM_callocN(sizeof(*handler), __func__); | wmEventHandler_Op *handler = MEM_callocN(sizeof(*handler), __func__); | ||||
| handler->head.type = WM_HANDLER_TYPE_OP; | handler->head.type = WM_HANDLER_TYPE_OP; | ||||
| handler->is_fileselect = true; | handler->is_fileselect = true; | ||||
| handler->op = op; | handler->op = op; | ||||
| handler->context.win = CTX_wm_window(C); | handler->context.win = CTX_wm_window(C); | ||||
| handler->context.area = CTX_wm_area(C); | handler->context.area = CTX_wm_area(C); | ||||
| handler->context.region = CTX_wm_region(C); | handler->context.region = CTX_wm_region(C); | ||||
| ▲ Show 20 Lines • Show All 1,768 Lines • Show Last 20 Lines | |||||
Maybe this closing logic should be moved into a ED_screen_temp_space_close(), although I'm a bit unsure which parts after calling wm_window_close() should be in a general function and which are specific to the file browser.
Right now the file browser would be the only caller anyway.