diff options
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 24 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 16 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_header.c | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_screen_types.h | 13 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 167 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 41 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_types.h | 15 |
10 files changed, 208 insertions, 93 deletions
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 1d1f31c4221..1cedc7b0282 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -457,11 +457,8 @@ int file_cancel_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); - if(sfile->op) { - WM_operator_free(sfile->op); - sfile->op = NULL; - } - ED_screen_full_prevspace(C); + WM_event_fileselect_event(C, sfile->op, EVT_FILESELECT_CANCEL); + sfile->op = NULL; return OPERATOR_FINISHED; } @@ -477,34 +474,21 @@ void FILE_OT_cancel(struct wmOperatorType *ot) ot->poll= ED_operator_file_active; } - +/* sends events now, so things get handled on windowqueue level */ int file_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); char name[FILE_MAX]; - ED_screen_full_prevspace(C); - if(sfile->op) { wmOperator *op= sfile->op; - /* if load .blend, all UI pointers after exec are invalid! */ - /* but, operator can be freed still */ - sfile->op = NULL; BLI_strncpy(name, sfile->params->dir, sizeof(name)); strcat(name, sfile->params->file); RNA_string_set(op->ptr, "filename", name); - /* a bit weak, might become arg for ED_fileselect? */ - if(strncmp(sfile->params->title, "Save", 4)==0) { - /* this gives ownership to pupmenu */ - uiPupMenuSaveOver(C, op, name); - } - else { - op->type->exec(C, op); - WM_operator_free(op); - } + WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index f8557a2b573..6eed864ff47 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -125,10 +125,6 @@ static void file_free(SpaceLink *sl) MEM_freeN(sfile->params); sfile->params= NULL; } - - if (sfile->op) { - WM_operator_free(sfile->op); - } } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 51bca9d4fcc..edbb960785d 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -63,7 +63,6 @@ #include "RNA_types.h" #include "ED_image.h" -#include "ED_fileselect.h" #include "ED_screen.h" #include "ED_space_api.h" #include "ED_uvedit.h" @@ -591,18 +590,8 @@ static char *filesel_imagetype_string(Image *ima) static void image_filesel(bContext *C, wmOperator *op, const char *path) { - SpaceFile *sfile; - - // XXX context is not set back ok afterwards - // ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_FILE); - ED_area_newspace(C, CTX_wm_area(C), SPACE_FILE); - - /* settings for filebrowser */ - sfile= (SpaceFile*)CTX_wm_space_data(C); - sfile->op= op; - - /* XXX right params for image save, with pupmenu and image type .. */ - ED_fileselect_set_params(sfile, FILE_SPECIAL, op->type->name, path, 0, 0, 0); + RNA_string_set(op->ptr, "filename", path); + WM_event_add_fileselect(C, op); } /******************** open image operator ********************/ @@ -834,6 +823,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event) sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype); // XXX activate_fileselect_menu(FILE_SPECIAL, "Save Image", name, strp, &sima->imtypenr, save_image_doit); + // XXX note: we can give default menu enums to operator for this image_filesel(C, op, ima->name); diff --git a/source/blender/editors/space_sequencer/sequencer_header.c b/source/blender/editors/space_sequencer/sequencer_header.c index 32a60f1fb54..71d7ff728d3 100644 --- a/source/blender/editors/space_sequencer/sequencer_header.c +++ b/source/blender/editors/space_sequencer/sequencer_header.c @@ -146,7 +146,7 @@ static uiBlock *seq_viewmenu(bContext *C, ARegion *ar, void *arg_unused) //static uiBlock *seq_selectmenu(bContext *C, ARegion *ar, void *arg_unused) static void seq_selectmenu(bContext *C, uiMenuItem *head, void *arg_unused) { - uiMenuContext(head, WM_OP_INVOKE_DEFAULT); + uiMenuContext(head, WM_OP_INVOKE_REGION_WIN); uiMenuItemEnumO(head, "Strips to the Left", 0, "SEQUENCER_OT_select_active_side", "side", SEQ_SIDE_LEFT); uiMenuItemEnumO(head, "Strips to the Right", 0, "SEQUENCER_OT_select_active_side", "side", SEQ_SIDE_RIGHT); @@ -212,7 +212,7 @@ static uiBlock *seq_markermenu(bContext *C, ARegion *ar, void *arg_unused) //static uiBlock *seq_addmenu_effectmenu(bContext *C, ARegion *ar, void *arg_unused) static void seq_addmenu_effectmenu(bContext *C, uiMenuItem *head, void *arg_unused) { - uiMenuContext(head, WM_OP_INVOKE_DEFAULT); + uiMenuContext(head, WM_OP_INVOKE_REGION_WIN); uiMenuItemEnumO(head, "", 0, "SEQUENCER_OT_add_effect_strip", "type", SEQ_ADD); uiMenuItemEnumO(head, "", 0, "SEQUENCER_OT_add_effect_strip", "type", SEQ_SUB); @@ -238,7 +238,7 @@ static void seq_addmenu(bContext *C, uiMenuItem *head, void *arg_unused) uiMenuLevel(head, "Effects...", seq_addmenu_effectmenu); uiMenuSeparator(head); - uiMenuContext(head, WM_OP_INVOKE_DEFAULT); + uiMenuContext(head, WM_OP_INVOKE_REGION_WIN); #ifdef WITH_FFMPEG uiMenuItemBooleanO(head, "Audio (RAM)", 0, "SEQUENCER_OT_add_sound_strip", "hd", FALSE); @@ -263,7 +263,7 @@ static void seq_editmenu(bContext *C, uiMenuItem *head, void *arg_unused) Scene *scene= CTX_data_scene(C); Editing *ed= seq_give_editing(scene, FALSE); - uiMenuContext(head, WM_OP_INVOKE_DEFAULT); + uiMenuContext(head, WM_OP_INVOKE_REGION_WIN); uiMenuItemEnumO(head, "", 0, "TFM_OT_transform", "mode", TFM_TRANSLATION); uiMenuItemEnumO(head, "", 0, "TFM_OT_transform", "mode", TFM_TIME_EXTEND); diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 89bf32ef16d..bc845ec177a 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -44,14 +44,15 @@ struct wmTimer; typedef struct bScreen { ID id; - ListBase vertbase, edgebase; + ListBase vertbase; /* screens have vertices/edges to define areas */ + ListBase edgebase; ListBase areabase; - ListBase regionbase; /* screen level regions, runtime only */ - struct Scene *scene; + ListBase regionbase; /* screen level regions (menus), runtime only */ - short scenenr, screennr; /* only for pupmenu */ + struct Scene *scene; - short full, winid; /* winid from WM, starts with 1 */ + short full; /* fade out? */ + short winid; /* winid from WM, starts with 1 */ short do_draw; /* notifier for drawing edges */ short do_refresh; /* notifier for scale screen, changed screen, etc */ short do_draw_gesture; /* notifier for gesture draw. */ @@ -62,6 +63,8 @@ typedef struct bScreen { short mainwin; /* screensize subwindow, for screenedges and global menus */ short subwinactive; /* active subwindow */ + int pad2; + struct wmTimer *animtimer; /* if set, screen has timer handler added in window */ void *context; /* context callback */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index f0f8996cca9..45dd2f3aee2 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -161,11 +161,15 @@ struct wmGesture *WM_gesture_new(struct bContext *C, struct wmEvent *event, int void WM_gesture_end(struct bContext *C, struct wmGesture *gesture); /* radial control operator */ -int WM_radial_control_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); -int WM_radial_control_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); +int WM_radial_control_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); +int WM_radial_control_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); void WM_OT_radial_control_partial(struct wmOperatorType *ot); void WM_radial_control_string(struct wmOperator *op, char str[], int maxlen); + /* fileselecting support */ +void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op); +void WM_event_fileselect_event(struct bContext *C, void *ophandle, int eventval); + /* OpenGL wrappers, mimicking opengl syntax */ void wmSubWindowSet (struct wmWindow *win, int swinid); void wmSubWindowScissorSet (struct wmWindow *win, int swinid, struct rcti *srct); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 1f417860e0c..80cef611974 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -50,6 +50,7 @@ #include "BKE_scene.h" #include "BKE_utildefines.h" +#include "ED_fileselect.h" #include "ED_screen.h" #include "ED_space_api.h" #include "ED_util.h" @@ -455,10 +456,36 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, PointerRNA *properties, /* ********************* handlers *************** */ -/* not handler itself, is called by UI to move handlers to other queues, so don't close modal ones */ +/* future extra customadata free? */ static void wm_event_free_handler(wmEventHandler *handler) { + MEM_freeN(handler); +} + +/* only set context when area/region is part of screen */ +static void wm_handler_op_context(bContext *C, wmEventHandler *handler) +{ + bScreen *screen= CTX_wm_screen(C); + if(screen && handler->op) { + ScrArea *sa; + + for(sa= screen->areabase.first; sa; sa= sa->next) + if(sa==handler->op_area) + break; + if(sa==NULL) + printf("internal error: handler (%s) has invalid area\n", handler->op->type->idname); + else { + ARegion *ar; + CTX_wm_area_set(C, sa); + for(ar= sa->regionbase.first; ar; ar= ar->next) + if(ar==handler->op_region) + break; + /* XXX no warning print here, after full-area and back regions are remade */ + if(ar) + CTX_wm_region_set(C, ar); + } + } } /* called on exit or remove area, only here call cancel callback */ @@ -475,8 +502,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) ScrArea *area= CTX_wm_area(C); ARegion *region= CTX_wm_region(C); - CTX_wm_area_set(C, handler->op_area); - CTX_wm_region_set(C, handler->op_region); + wm_handler_op_context(C, handler); handler->op->type->cancel(C, handler->op); @@ -500,7 +526,6 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) } wm_event_free_handler(handler); - MEM_freeN(handler); } } @@ -597,8 +622,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand ScrArea *area= CTX_wm_area(C); ARegion *region= CTX_wm_region(C); - CTX_wm_area_set(C, handler->op_area); - CTX_wm_region_set(C, handler->op_region); + wm_handler_op_context(C, handler); retval= ot->modal(C, op, event); @@ -641,7 +665,6 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) { BLI_remlink(handlers, handler); wm_event_free_handler(handler); - MEM_freeN(handler); /* prevent silly errors from operator users */ //retval &= ~OPERATOR_PASS_THROUGH; @@ -693,6 +716,87 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve return WM_HANDLER_CONTINUE; } +/* fileselect handlers are only in the window queue, so it's save to switch screens or area types */ +static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event) +{ + SpaceFile *sfile; + int action= WM_HANDLER_CONTINUE; + + if(event->type != EVT_FILESELECT) + return action; + if(handler->op != (wmOperator *)event->customdata) + return action; + + switch(event->val) { + case EVT_FILESELECT_OPEN: + case EVT_FILESELECT_FULL_OPEN: + { + int filetype= FILE_BLENDER; + char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); + + if(RNA_struct_find_property(handler->op->ptr, "filetype")) + filetype= RNA_int_get(handler->op->ptr, "filetype"); + + if(event->val==EVT_FILESELECT_OPEN) + ED_area_newspace(C, handler->op_area, SPACE_FILE); + else + ED_screen_full_newspace(C, handler->op_area, SPACE_FILE); + + /* settings for filebrowser, sfile is not operator owner but sends events */ + sfile= (SpaceFile*)CTX_wm_space_data(C); + sfile->op= handler->op; + + ED_fileselect_set_params(sfile, filetype, handler->op->type->name, path, 0, 0, 0); + MEM_freeN(path); + + action= WM_HANDLER_BREAK; + } + break; + + case EVT_FILESELECT_EXEC: + case EVT_FILESELECT_CANCEL: + { + /* XXX validate area and region? */ + bScreen *screen= CTX_wm_screen(C); + char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); + + if(screen != handler->filescreen) + ED_screen_full_prevspace(C); + else + ED_area_prevspace(C); + + /* remlink now, for load file case */ + BLI_remlink(handlers, handler); + + if(event->val==EVT_FILESELECT_EXEC) { + wm_handler_op_context(C, handler); + + /* a bit weak, might become arg for WM_event_fileselect? */ + if(strncmp(handler->op->type->name, "Save", 4)==0) { + /* this gives ownership to pupmenu */ + uiPupMenuSaveOver(C, handler->op, path); + } + else { + handler->op->type->exec(C, handler->op); + WM_operator_free(handler->op); + } + + CTX_wm_area_set(C, NULL); + } + else + WM_operator_free(handler->op); + + wm_event_free_handler(handler); + MEM_freeN(path); + + action= WM_HANDLER_BREAK; + } + break; + } + + return action; +} + static int handler_boundbox_test(wmEventHandler *handler, wmEvent *event) { if(handler->bbwin) { @@ -742,6 +846,10 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) else if(handler->ui_handle) { action= wm_handler_ui_call(C, handler, event); } + else if(handler->type==WM_HANDLER_FILESELECT) { + /* screen context changes here */ + action= wm_handler_fileselect_call(C, handlers, handler, event); + } else { /* modal, swallows all */ action= wm_handler_operator_call(C, handlers, handler, event, NULL); @@ -930,6 +1038,49 @@ void wm_event_do_handlers(bContext *C) } } +/* ********** filesector handling ************ */ + +void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval) +{ + /* add to all windows! */ + wmWindow *win; + + for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) { + wmEvent event= *win->eventstate; + + event.type= EVT_FILESELECT; + event.val= eventval; + event.customdata= ophandle; // only as void pointer type check + + wm_event_add(win, &event); + } +} + +/* operator is supposed to have a filled "filename" property */ +/* optional property: filetype (XXX enum?) */ + +/* Idea is to keep a handler alive on window queue, owning the operator. + The filewindow can send event to make it execute, thus ensuring + executing happens outside of lower level queues, with UI refreshed. + Should also allow multiwin solutions */ + +void WM_event_add_fileselect(bContext *C, wmOperator *op) +{ + wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "fileselect handler"); + wmWindow *win= CTX_wm_window(C); + int full= 1; // XXX preset? + + handler->type= WM_HANDLER_FILESELECT; + handler->op= op; + handler->op_area= CTX_wm_area(C); + handler->op_region= CTX_wm_region(C); + handler->filescreen= CTX_wm_screen(C); + + BLI_addhead(&win->handlers, handler); + + WM_event_fileselect_event(C, op, full?EVT_FILESELECT_FULL_OPEN:EVT_FILESELECT_OPEN); +} + /* lets not expose struct outside wm? */ void WM_event_set_handler_flag(wmEventHandler *handler, int flag) { @@ -997,7 +1148,6 @@ void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap) if(handler->keymap==keymap) { BLI_remlink(handlers, handler); wm_event_free_handler(handler); - MEM_freeN(handler); break; } } @@ -1025,7 +1175,6 @@ void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHa if(handler->ui_handle == func && handler->ui_remove == remove && handler->ui_userdata == userdata) { BLI_remlink(handlers, handler); wm_event_free_handler(handler); - MEM_freeN(handler); break; } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8372aa17208..9626fda6ffe 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -53,7 +53,6 @@ #include "BIF_glutil.h" /* for paint cursor */ #include "IMB_imbuf_types.h" -#include "ED_fileselect.h" #include "ED_screen.h" #include "RNA_access.h" @@ -235,17 +234,9 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event) { if (RNA_property_is_set(op->ptr, "filename")) { return WM_operator_call(C, op); - } else { - SpaceFile *sfile; - - ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_FILE); - - /* settings for filebrowser */ - sfile= (SpaceFile*)CTX_wm_space_data(C); - sfile->op = op; - ED_fileselect_set_params(sfile, FILE_BLENDER, op->type->name, "", 0, 0, 0); - - /* screen and area have been reset already in ED_screen_full_newspace */ + } + else { + WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; } } @@ -368,18 +359,9 @@ static void untitled(char *name) static int wm_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) { - SpaceFile *sfile; - - if(0==ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_FILE)) - return OPERATOR_CANCELLED; - - /* settings for filebrowser */ - sfile= (SpaceFile*)CTX_wm_space_data(C); - sfile->op = op; - - ED_fileselect_set_params(sfile, FILE_BLENDER, "Load", G.sce, 0, 0, 0); - /* screen and area have been reset already in ED_screen_full_newspace */ + RNA_string_set(op->ptr, "filename", G.sce); + WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; } @@ -415,20 +397,13 @@ static void WM_OT_open_mainfile(wmOperatorType *ot) static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) { - SpaceFile *sfile; char name[FILE_MAX]; - ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_FILE); - - /* settings for filebrowser */ - sfile= (SpaceFile*)CTX_wm_space_data(C); - sfile->op = op; - BLI_strncpy(name, G.sce, FILE_MAX); untitled(name); - ED_fileselect_set_params(sfile, FILE_BLENDER, "Save As", name, 0, 0, 0); - - /* screen and area have been reset already in ED_screen_full_newspace */ + RNA_string_set(op->ptr, "filename", name); + + WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index d6899d47471..930f20dfa63 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -59,6 +59,9 @@ typedef struct wmEventHandler { struct ScrArea *ui_area; /* for derived/modal handlers */ struct ARegion *ui_region; /* for derived/modal handlers */ + /* fileselect handler re-uses modal operator data */ + struct bScreen *filescreen; /* screen it started in, to validate exec */ + } wmEventHandler; @@ -71,7 +74,7 @@ typedef struct wmEventHandler { /* custom types for handlers, for signalling, freeing */ enum { WM_HANDLER_DEFAULT, - WM_HANDLER_TRANSFORM + WM_HANDLER_FILESELECT }; diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index a3bf0ca728f..275d8d99810 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -197,7 +197,7 @@ #define ISKEYBOARD(event) (event >='a' && event <=255) -/* **************** BLENDER QUEUE EVENTS ********************* */ +/* **************** XXX depricated! BLENDER QUEUE EVENTS ********************* */ #define CHANGED 0x4000 #define DRAWEDGES 0x4001 @@ -211,7 +211,6 @@ #define AUTOSAVE_FILE 0x4009 #define UNDOPUSH 0x400A -/* REDRAWVIEW3D has to be the first one (lowest number) for buttons! */ #define REDRAWVIEW3D 0x4010 #define REDRAWVIEWCAM 0x4011 #define REDRAWVIEW3D_Z 0x4012 @@ -293,5 +292,17 @@ #define EVT_GESTURE_W_S 15 #define EVT_GESTURE_W_N 16 +/* **************** OTHER BLENDER EVENTS ********************* */ + +/* event->type */ +#define EVT_FILESELECT 0x5020 + +/* event->val */ +#define EVT_FILESELECT_OPEN 1 +#define EVT_FILESELECT_FULL_OPEN 2 +#define EVT_FILESELECT_EXEC 3 +#define EVT_FILESELECT_CANCEL 4 + + #endif /* WM_EVENT_TYPES_H */ |