diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_operators.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 112 |
1 files changed, 82 insertions, 30 deletions
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7e93c2d5f46..32d2adffb01 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -921,7 +921,16 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) if(ED_undo_valid(C, op->type->name)==0) uiLayoutSetEnabled(layout, 0); - uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE); + if(op->type->flag & OPTYPE_MACRO) { + for(op= op->macro.first; op; op= op->next) { + uiItemL(layout, op->type->name, ICON_NONE); + uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE); + } + } + else { + uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE); + } + uiPopupBoundsBlock(block, 4, 0, 0); uiEndBlock(C, block); @@ -929,13 +938,28 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) return block; } -/* Only invoked by OK button in popups created with wm_block_create_dialog() */ +typedef struct wmOpPopUp +{ + wmOperator *op; + int width; + int height; + int free_op; +} wmOpPopUp; + +/* Only invoked by OK button in popups created with wm_block_dialog_create() */ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2) { - wmOperator *op= arg1; + wmOpPopUp *data= arg1; uiBlock *block= arg2; - WM_operator_call(C, op); + WM_operator_call(C, data->op); + + /* let execute handle freeing it */ + //data->free_op= FALSE; + //data->op= NULL; + + /* in this case, wm_operator_ui_popup_cancel wont run */ + MEM_freeN(data); uiPupBlockClose(C, block); } @@ -951,9 +975,9 @@ static void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg)) } /* Dialogs are popups that require user verification (click OK) before exec */ -static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData) +static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData) { - struct { wmOperator *op; int width; int height; } * data = userData; + wmOpPopUp *data= userData; wmOperator *op= data->op; uiBlock *block; uiLayout *layout; @@ -982,7 +1006,7 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData) col_block= uiLayoutGetBlock(col); /* Create OK button, the callback of which will execute op */ btn= uiDefBut(col_block, BUT, 0, "OK", 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); - uiButSetFunc(btn, dialog_exec_cb, op, col_block); + uiButSetFunc(btn, dialog_exec_cb, data, col_block); } /* center around the mouse */ @@ -992,9 +1016,9 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData) return block; } -static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData) +static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData) { - struct { wmOperator *op; int width; int height; } * data = userData; + wmOpPopUp *data= userData; wmOperator *op= data->op; uiBlock *block; uiLayout *layout; @@ -1015,6 +1039,28 @@ static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData) return block; } +static void wm_operator_ui_popup_cancel(void *userData) +{ + wmOpPopUp *data= userData; + if(data->free_op && data->op) { + wmOperator *op= data->op; + WM_operator_free(op); + } + + MEM_freeN(data); +} + +int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height) +{ + wmOpPopUp *data= MEM_callocN(sizeof(wmOpPopUp), "WM_operator_ui_popup"); + data->op= op; + data->width= width; + data->height= height; + data->free_op= TRUE; /* if this runs and gets registered we may want not to free it */ + uiPupBlockEx(C, wm_operator_ui_create, wm_operator_ui_popup_cancel, data); + return OPERATOR_RUNNING_MODAL; +} + /* operator menu needs undo, for redo callback */ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { @@ -1034,28 +1080,19 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height) { - struct { wmOperator *op; int width; int height; } data; + wmOpPopUp *data= MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup"); - data.op= op; - data.width= width; - data.height= height; + data->op= op; + data->width= width; + data->height= height; + data->free_op= TRUE; /* if this runs and gets registered we may want not to free it */ /* op is not executed until popup OK but is clicked */ - uiPupBlock(C, wm_block_create_dialog, &data); + uiPupBlockEx(C, wm_block_dialog_create, wm_operator_ui_popup_cancel, data); return OPERATOR_RUNNING_MODAL; } -int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height) -{ - struct { wmOperator *op; int width; int height; } data; - data.op = op; - data.width = width; - data.height = height; - uiPupBlock(C, wm_operator_create_ui, &data); - return OPERATOR_RUNNING_MODAL; -} - int WM_operator_redo_popup(bContext *C, wmOperator *op) { /* CTX_wm_reports(C) because operator is on stack, not active in event system */ @@ -1210,7 +1247,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar col = uiLayoutColumn(split, 0); uiItemL(col, "Links", ICON_NONE); uiItemStringO(col, "Donations", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/blenderorg/blender-foundation/donation-payment/"); - uiItemStringO(col, "Release Log", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-257/"); + uiItemStringO(col, "Release Log", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-258/"); uiItemStringO(col, "Manual", ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.5/Manual"); uiItemStringO(col, "Blender Website", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/"); uiItemStringO(col, "User Community", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/community/user-community/"); // @@ -1583,6 +1620,14 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED( { const char *openname= G.main->name; + if(CTX_wm_window(C) == NULL) { + /* in rare cases this could happen, when trying to invoke in background + * mode on load for example. Don't use poll for this because exec() + * can still run without a window */ + BKE_report(op->reports, RPT_ERROR, "Context window not set"); + return OPERATOR_CANCELLED; + } + /* if possible, get the name of the most recently used .blend file */ if (G.recent_files.first) { struct RecentFile *recent = G.recent_files.first; @@ -1633,7 +1678,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot) ot->invoke= wm_open_mainfile_invoke; ot->exec= wm_open_mainfile_exec; - ot->poll= WM_operator_winactive; + /* ommit window poll so this can work in background mode */ WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH); @@ -2052,7 +2097,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) ot->invoke= wm_save_mainfile_invoke; ot->exec= wm_save_as_mainfile_exec; ot->check= blend_save_check; - ot->poll= NULL; + /* ommit window poll so this can work in background mode */ WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file"); @@ -2066,6 +2111,8 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { + int selected = 0; + if(!RNA_property_is_set(op->ptr, "filepath")) { char filepath[FILE_MAX]; BLI_strncpy(filepath, G.main->name, sizeof(filepath)); @@ -2082,6 +2129,7 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filename[FILE_MAX]; + int selected; if(!RNA_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); @@ -2089,7 +2137,8 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) } RNA_string_get(op->ptr, "filepath", filename); - if(collada_export(CTX_data_scene(C), filename)) { + selected = RNA_boolean_get(op->ptr, "selected"); + if(collada_export(CTX_data_scene(C), filename, selected)) { return OPERATOR_FINISHED; } else { @@ -2107,6 +2156,8 @@ static void WM_OT_collada_export(wmOperatorType *ot) ot->poll= WM_operator_winactive; WM_operator_properties_filesel(ot, FOLDERFILE|COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH); + RNA_def_boolean(ot->srna, "selected", 0, "Export only selected", + "Export only selected elements"); } /* function used for WM_OT_save_mainfile too */ @@ -3232,7 +3283,6 @@ static int radial_control_cancel(bContext *C, wmOperator *op) static int radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) { RadialControl *rc = op->customdata; - wmWindowManager *wm; float new_value, dist, zoom[2]; float delta[2], snap, ret = OPERATOR_RUNNING_MODAL; @@ -3625,10 +3675,12 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) /* items for modal map */ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); - WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL); + /* Note: cancel only on press otherwise you cannot map this to RMB-gesture */ + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); #if 0 // Durian guys like this WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN); |