forked from bartvdbraak/blender
UI: Optional prompt to quit for non win32 systems
D566 by @januz Use Blender native dialog when OS dialog's aren't supported.
This commit is contained in:
parent
23ffd4ec39
commit
5ba5254ec1
@ -897,6 +897,11 @@ extern int GHOST_toggleConsole(int action);
|
||||
*/
|
||||
extern int GHOST_confirmQuit(GHOST_WindowHandle windowhandle);
|
||||
|
||||
/**
|
||||
* Informs if the system provides native dialogs (eg. confirm quit)
|
||||
*/
|
||||
extern int GHOST_SupportsNativeDialogs(void);
|
||||
|
||||
/**
|
||||
* Use native pixel size (MacBook pro 'retina'), if supported.
|
||||
*/
|
||||
|
@ -418,6 +418,12 @@ public:
|
||||
* in the application
|
||||
*/
|
||||
virtual int confirmQuit(GHOST_IWindow *window) const = 0;
|
||||
|
||||
/**
|
||||
* Informs if the system provides native dialogs (eg. confirm quit)
|
||||
*/
|
||||
virtual bool supportsNativeDialogs(void) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Initialize the system.
|
||||
|
@ -893,6 +893,11 @@ int GHOST_toggleConsole(int action)
|
||||
return system->toggleConsole(action);
|
||||
}
|
||||
|
||||
int GHOST_SupportsNativeDialogs(void)
|
||||
{
|
||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
||||
return system->supportsNativeDialogs();
|
||||
}
|
||||
|
||||
int GHOST_confirmQuit(GHOST_WindowHandle windowhandle)
|
||||
{
|
||||
|
@ -380,6 +380,11 @@ int GHOST_System::confirmQuit(GHOST_IWindow * /*window*/) const
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool GHOST_System::supportsNativeDialogs(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool GHOST_System::useNativePixel(void)
|
||||
{
|
||||
m_nativePixel = true;
|
||||
|
@ -319,6 +319,10 @@ public:
|
||||
*/
|
||||
virtual int confirmQuit(GHOST_IWindow *window) const;
|
||||
|
||||
/**
|
||||
* Informs if the system provides native dialogs (eg. confirm quit)
|
||||
*/
|
||||
virtual bool supportsNativeDialogs(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) { return GHOST_kFailure; }
|
||||
void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ }
|
||||
void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ }
|
||||
bool supportsNativeDialogs(void) { return false;}
|
||||
|
||||
GHOST_TSuccess init() {
|
||||
GHOST_TSuccess success = GHOST_System::init();
|
||||
|
@ -635,6 +635,11 @@ GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind)
|
||||
m_dirty_windows.push_back(bad_wind);
|
||||
}
|
||||
|
||||
bool
|
||||
GHOST_SystemSDL::supportsNativeDialogs(void)
|
||||
{
|
||||
return false
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons& buttons) const
|
||||
{
|
||||
|
@ -95,6 +95,10 @@ public:
|
||||
getMainDisplayDimensions(GHOST_TUns32& width,
|
||||
GHOST_TUns32& height) const;
|
||||
|
||||
/**
|
||||
* Informs if the system provides native dialogs (eg. confirm quit)
|
||||
*/
|
||||
virtual bool supportsNativeDialogs(void);
|
||||
private:
|
||||
|
||||
GHOST_TSuccess
|
||||
|
@ -379,6 +379,11 @@ createWindow(const STR_String& title,
|
||||
return window;
|
||||
}
|
||||
|
||||
bool GHOST_SystemX11::supportsNativeDialogs(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
|
||||
static void destroyIMCallback(XIM /*xim*/, XPointer ptr, XPointer /*data*/)
|
||||
{
|
||||
|
@ -97,6 +97,10 @@ public:
|
||||
init(
|
||||
);
|
||||
|
||||
/**
|
||||
* Informs if the system provides native dialogs (eg. confirm quit)
|
||||
*/
|
||||
virtual bool supportsNativeDialogs(void);
|
||||
|
||||
/**
|
||||
* \section Interface Inherited from GHOST_ISystem
|
||||
|
@ -211,7 +211,6 @@ class USERPREF_PT_interface(Panel):
|
||||
return (userpref.active_section == 'INTERFACE')
|
||||
|
||||
def draw(self, context):
|
||||
import sys
|
||||
layout = self.layout
|
||||
|
||||
userpref = context.user_preferences
|
||||
@ -244,9 +243,8 @@ class USERPREF_PT_interface(Panel):
|
||||
|
||||
col.separator()
|
||||
|
||||
if sys.platform[:3] == "win":
|
||||
col.label("Warnings")
|
||||
col.prop(view, "use_quit_dialog")
|
||||
col.label("Warnings")
|
||||
col.prop(view, "use_quit_dialog")
|
||||
|
||||
row.separator()
|
||||
row.separator()
|
||||
|
@ -2075,6 +2075,10 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
|
||||
|
||||
WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL);
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "exit")) {
|
||||
WM_exit(C);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@ -2174,12 +2178,16 @@ void WM_OT_save_mainfile(wmOperatorType *ot)
|
||||
ot->check = blend_save_check;
|
||||
/* omit window poll so this can work in background mode */
|
||||
|
||||
PropertyRNA *prop;
|
||||
WM_operator_properties_filesel(
|
||||
ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_SAVE,
|
||||
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
|
||||
RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file");
|
||||
RNA_def_boolean(ot->srna, "relative_remap", false, "Remap Relative",
|
||||
"Remap relative paths when saving in a different directory");
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "exit", false, "Exit", "Exit Blender after saving");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -2162,10 +2162,16 @@ static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
|
||||
|
||||
static int wm_exit_blender_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
WM_operator_free(op);
|
||||
|
||||
WM_exit(C);
|
||||
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
|
||||
if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) {
|
||||
wm_confirm_quit(C);
|
||||
}
|
||||
else {
|
||||
WM_operator_free(op);
|
||||
WM_exit(C);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@ -2175,7 +2181,6 @@ static void WM_OT_quit_blender(wmOperatorType *ot)
|
||||
ot->idname = "WM_OT_quit_blender";
|
||||
ot->description = "Quit Blender";
|
||||
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = wm_exit_blender_exec;
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "ED_fileselect.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
@ -295,6 +296,124 @@ wmWindow *wm_window_copy_test(bContext *C, wmWindow *win_src)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Quit Confirmation Dialog
|
||||
* \{ */
|
||||
|
||||
/** Cancel quitting and close the dialog */
|
||||
static void wm_block_confirm_quit_cancel(bContext *C, void *arg_block, void *UNUSED(arg))
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
UI_popup_block_close(C, win, arg_block);
|
||||
}
|
||||
|
||||
/** Discard the file changes and quit */
|
||||
static void wm_block_confirm_quit_discard(bContext *C, void *arg_block, void *UNUSED(arg))
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
UI_popup_block_close(C, win, arg_block);
|
||||
WM_exit(C);
|
||||
}
|
||||
|
||||
/* Save changes and quit */
|
||||
static void wm_block_confirm_quit_save(bContext *C, void *arg_block, void *UNUSED(arg))
|
||||
{
|
||||
PointerRNA props_ptr;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
UI_popup_block_close(C, win, arg_block);
|
||||
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_save_mainfile", false);
|
||||
|
||||
WM_operator_properties_create_ptr(&props_ptr, ot);
|
||||
RNA_boolean_set(&props_ptr, "exit", true);
|
||||
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
|
||||
WM_operator_properties_free(&props_ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Build the confirm dialog UI */
|
||||
static uiBlock *block_create_confirm_quit(struct bContext *C, struct ARegion *ar, void *UNUSED(arg1))
|
||||
{
|
||||
|
||||
uiStyle *style = UI_style_get();
|
||||
uiBlock *block = UI_block_begin(C, ar, "confirm_quit_popup", UI_EMBOSS);
|
||||
|
||||
UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP );
|
||||
UI_block_emboss_set(block, UI_EMBOSS);
|
||||
|
||||
uiLayout *layout = UI_block_layout(
|
||||
block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style);
|
||||
|
||||
/* Text and some vertical space */
|
||||
{
|
||||
char *message;
|
||||
if (G.main->name[0] == '\0') {
|
||||
message = BLI_strdup(IFACE_("This file has not been saved yet. Save before closing?"));
|
||||
}
|
||||
else {
|
||||
const char *basename = BLI_path_basename(G.main->name);
|
||||
message = BLI_sprintfN(IFACE_("Save changes to \"%s\" before closing?"), basename);
|
||||
}
|
||||
uiItemL(layout, message, ICON_ERROR);
|
||||
MEM_freeN(message);
|
||||
}
|
||||
|
||||
uiItemS(layout);
|
||||
uiItemS(layout);
|
||||
|
||||
|
||||
/* Buttons */
|
||||
uiBut *but;
|
||||
|
||||
uiLayout *split = uiLayoutSplit(layout, 0.0f, true);
|
||||
|
||||
uiLayout *col = uiLayoutColumn(split, false);
|
||||
|
||||
but = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, ICON_SCREEN_BACK, IFACE_("Cancel"), 0, 0, 0, UI_UNIT_Y,
|
||||
NULL, 0, 0, 0, 0, TIP_("Do not quit"));
|
||||
UI_but_func_set(but, wm_block_confirm_quit_cancel, block, NULL);
|
||||
|
||||
/* empty space between buttons */
|
||||
col = uiLayoutColumn(split, false);
|
||||
uiItemS(col);
|
||||
|
||||
col = uiLayoutColumn(split, 1);
|
||||
but = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, ICON_CANCEL, IFACE_("Discard Changes"), 0, 0, 50, UI_UNIT_Y,
|
||||
NULL, 0, 0, 0, 0, TIP_("Discard changes and quit"));
|
||||
UI_but_func_set(but, wm_block_confirm_quit_discard, block, NULL);
|
||||
|
||||
col = uiLayoutColumn(split, 1);
|
||||
but = uiDefIconTextBut(
|
||||
block, UI_BTYPE_BUT, 0, ICON_FILE_TICK, IFACE_("Save & Quit"), 0, 0, 50, UI_UNIT_Y,
|
||||
NULL, 0, 0, 0, 0, TIP_("Save and quit"));
|
||||
UI_but_func_set(but, wm_block_confirm_quit_save, block, NULL);
|
||||
|
||||
UI_block_bounds_set_centered(block, 10);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
/** Call the confirm dialog on quitting. */
|
||||
void wm_confirm_quit(bContext *C)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
|
||||
/* The popup needs to have a window set in context to show up since
|
||||
* it's being called outside the normal operator event handling loop */
|
||||
if (wm->winactive) {
|
||||
CTX_wm_window_set(C, wm->winactive);
|
||||
}
|
||||
|
||||
UI_popup_block_invoke(C, block_create_confirm_quit, NULL);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* this is event from ghost, or exit-blender op */
|
||||
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
|
||||
{
|
||||
@ -311,19 +430,24 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
|
||||
|
||||
if (tmpwin == NULL)
|
||||
do_exit = 1;
|
||||
|
||||
if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved && !G.background) {
|
||||
if (do_exit) {
|
||||
|
||||
if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved && !G.background && do_exit) {
|
||||
/* We have unsaved changes and we're quitting */
|
||||
if(GHOST_SupportsNativeDialogs() == 0) {
|
||||
wm_confirm_quit(C);
|
||||
}
|
||||
else {
|
||||
if (!GHOST_confirmQuit(win->ghostwin))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* let WM_exit do all freeing, for correct quit.blend save */
|
||||
if (do_exit) {
|
||||
else if (do_exit) {
|
||||
/* No changes but we're quitting */
|
||||
/* let WM_exit do all freeing, for correct quit.blend save */
|
||||
WM_exit(C);
|
||||
}
|
||||
else {
|
||||
/* We're just closing a window */
|
||||
bScreen *screen = win->screen;
|
||||
|
||||
BLI_remlink(&wm->windows, win);
|
||||
|
@ -78,6 +78,7 @@ void wm_window_IME_end (wmWindow *win);
|
||||
int wm_window_close_exec(bContext *C, struct wmOperator *op);
|
||||
int wm_window_duplicate_exec(bContext *C, struct wmOperator *op);
|
||||
int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
|
||||
void wm_confirm_quit(bContext *C);
|
||||
|
||||
/* Initial (unmaximized) size to start with for
|
||||
* systems that can't find it for themselves (X11).
|
||||
|
Loading…
Reference in New Issue
Block a user