Merge pull request #4029 from leethomas/show-message-box-default-button
Show message box default button
This commit is contained in:
commit
edcd34d4ce
7 changed files with 60 additions and 22 deletions
|
@ -41,6 +41,7 @@ namespace {
|
||||||
|
|
||||||
void ShowMessageBox(int type,
|
void ShowMessageBox(int type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
@ -54,12 +55,13 @@ void ShowMessageBox(int type,
|
||||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
||||||
peek,
|
peek,
|
||||||
&callback)) {
|
&callback)) {
|
||||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, cancel_id,
|
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons,
|
||||||
options, title, message, detail, icon, callback);
|
default_id, cancel_id, options, title,
|
||||||
|
message, detail, icon, callback);
|
||||||
} else {
|
} else {
|
||||||
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
||||||
buttons, cancel_id, options, title,
|
buttons, default_id, cancel_id,
|
||||||
message, detail, icon);
|
options, title, message, detail, icon);
|
||||||
args->Return(chosen);
|
args->Return(chosen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ module.exports =
|
||||||
options.message ?= ''
|
options.message ?= ''
|
||||||
options.detail ?= ''
|
options.detail ?= ''
|
||||||
options.icon ?= null
|
options.icon ?= null
|
||||||
|
options.defaultId ?= -1
|
||||||
|
|
||||||
# Choose a default button to get selected when dialog is cancelled.
|
# Choose a default button to get selected when dialog is cancelled.
|
||||||
unless options.cancelId?
|
unless options.cancelId?
|
||||||
|
@ -108,6 +109,7 @@ module.exports =
|
||||||
|
|
||||||
binding.showMessageBox messageBoxType,
|
binding.showMessageBox messageBoxType,
|
||||||
options.buttons,
|
options.buttons,
|
||||||
|
options.defaultId,
|
||||||
options.cancelId,
|
options.cancelId,
|
||||||
flags,
|
flags,
|
||||||
options.title,
|
options.title,
|
||||||
|
|
|
@ -38,6 +38,7 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
|
int default_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
|
@ -47,6 +48,7 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
void ShowMessageBox(NativeWindow* parent_window,
|
void ShowMessageBox(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
|
|
@ -29,6 +29,7 @@ class GtkMessageBox {
|
||||||
GtkMessageBox(NativeWindow* parent_window,
|
GtkMessageBox(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
|
@ -60,10 +61,17 @@ class GtkMessageBox {
|
||||||
|
|
||||||
// Add buttons.
|
// Add buttons.
|
||||||
for (size_t i = 0; i < buttons.size(); ++i) {
|
for (size_t i = 0; i < buttons.size(); ++i) {
|
||||||
|
if (i == (size_t)default_id) {
|
||||||
|
GtkWidget* button = gtk_dialog_add_button(GTK_DIALOG(dialog_),
|
||||||
|
TranslateToStock(i, buttons[i]),
|
||||||
|
i);
|
||||||
|
gtk_widget_grab_focus(button);
|
||||||
|
} else {
|
||||||
gtk_dialog_add_button(GTK_DIALOG(dialog_),
|
gtk_dialog_add_button(GTK_DIALOG(dialog_),
|
||||||
TranslateToStock(i, buttons[i]),
|
TranslateToStock(i, buttons[i]),
|
||||||
i);
|
i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parent window.
|
// Parent window.
|
||||||
if (parent_window) {
|
if (parent_window) {
|
||||||
|
@ -161,19 +169,21 @@ void GtkMessageBox::OnResponseDialog(GtkWidget* widget, int response) {
|
||||||
int ShowMessageBox(NativeWindow* parent,
|
int ShowMessageBox(NativeWindow* parent,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::string& detail,
|
const std::string& detail,
|
||||||
const gfx::ImageSkia& icon) {
|
const gfx::ImageSkia& icon) {
|
||||||
return GtkMessageBox(parent, type, buttons, cancel_id, title, message, detail,
|
return GtkMessageBox(parent, type, buttons, default_id, cancel_id,
|
||||||
icon).RunSynchronous();
|
title, message, detail, icon).RunSynchronous();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowMessageBox(NativeWindow* parent,
|
void ShowMessageBox(NativeWindow* parent,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
@ -181,13 +191,13 @@ void ShowMessageBox(NativeWindow* parent,
|
||||||
const std::string& detail,
|
const std::string& detail,
|
||||||
const gfx::ImageSkia& icon,
|
const gfx::ImageSkia& icon,
|
||||||
const MessageBoxCallback& callback) {
|
const MessageBoxCallback& callback) {
|
||||||
(new GtkMessageBox(parent, type, buttons, cancel_id, title, message, detail,
|
(new GtkMessageBox(parent, type, buttons, default_id, cancel_id,
|
||||||
icon))->RunAsynchronous(callback);
|
title, message, detail, icon))->RunAsynchronous(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
||||||
if (Browser::Get()->is_ready()) {
|
if (Browser::Get()->is_ready()) {
|
||||||
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, { "OK" }, 0, "Error",
|
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, { "OK" }, -1, 0, "Error",
|
||||||
base::UTF16ToUTF8(title).c_str(),
|
base::UTF16ToUTF8(title).c_str(),
|
||||||
base::UTF16ToUTF8(content).c_str(),
|
base::UTF16ToUTF8(content).c_str(),
|
||||||
gfx::ImageSkia()).RunSynchronous();
|
gfx::ImageSkia()).RunSynchronous();
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace {
|
||||||
NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const std::string& detail) {
|
const std::string& detail) {
|
||||||
|
@ -78,8 +79,17 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
||||||
// An empty title causes crash on OS X.
|
// An empty title causes crash on OS X.
|
||||||
if (buttons[i].empty())
|
if (buttons[i].empty())
|
||||||
title = @"(empty)";
|
title = @"(empty)";
|
||||||
|
|
||||||
NSButton* button = [alert addButtonWithTitle:title];
|
NSButton* button = [alert addButtonWithTitle:title];
|
||||||
[button setTag:i];
|
[button setTag:i];
|
||||||
|
|
||||||
|
if (i == (size_t)default_id) {
|
||||||
|
// Focus the button at default_id if the user opted to do so.
|
||||||
|
// The first button added gets set as the default selected.
|
||||||
|
// So remove that default, and make the requested button the default.
|
||||||
|
[[[alert buttons] objectAtIndex:0] setKeyEquivalent:@""];
|
||||||
|
[button setKeyEquivalent:@"\r"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return alert;
|
return alert;
|
||||||
|
@ -94,6 +104,7 @@ void SetReturnCode(int* ret_code, int result) {
|
||||||
int ShowMessageBox(NativeWindow* parent_window,
|
int ShowMessageBox(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
@ -101,7 +112,8 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
const std::string& detail,
|
const std::string& detail,
|
||||||
const gfx::ImageSkia& icon) {
|
const gfx::ImageSkia& icon) {
|
||||||
NSAlert* alert = CreateNSAlert(
|
NSAlert* alert = CreateNSAlert(
|
||||||
parent_window, type, buttons, title, message, detail);
|
parent_window, type, buttons, default_id, title, message,
|
||||||
|
detail);
|
||||||
|
|
||||||
// Use runModal for synchronous alert without parent, since we don't have a
|
// Use runModal for synchronous alert without parent, since we don't have a
|
||||||
// window to wait for.
|
// window to wait for.
|
||||||
|
@ -127,6 +139,7 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||||
void ShowMessageBox(NativeWindow* parent_window,
|
void ShowMessageBox(NativeWindow* parent_window,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
@ -135,7 +148,8 @@ void ShowMessageBox(NativeWindow* parent_window,
|
||||||
const gfx::ImageSkia& icon,
|
const gfx::ImageSkia& icon,
|
||||||
const MessageBoxCallback& callback) {
|
const MessageBoxCallback& callback) {
|
||||||
NSAlert* alert = CreateNSAlert(
|
NSAlert* alert = CreateNSAlert(
|
||||||
parent_window, type, buttons, title, message, detail);
|
parent_window, type, buttons, default_id, title, message,
|
||||||
|
detail);
|
||||||
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
|
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
|
||||||
andAlert:alert
|
andAlert:alert
|
||||||
callEndModal:false];
|
callEndModal:false];
|
||||||
|
|
|
@ -72,6 +72,7 @@ void MapToCommonID(const std::vector<base::string16>& buttons,
|
||||||
int ShowMessageBoxUTF16(HWND parent,
|
int ShowMessageBoxUTF16(HWND parent,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<base::string16>& buttons,
|
const std::vector<base::string16>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const base::string16& title,
|
const base::string16& title,
|
||||||
|
@ -87,6 +88,7 @@ int ShowMessageBoxUTF16(HWND parent,
|
||||||
config.hwndParent = parent;
|
config.hwndParent = parent;
|
||||||
config.hInstance = GetModuleHandle(NULL);
|
config.hInstance = GetModuleHandle(NULL);
|
||||||
config.dwFlags = flags;
|
config.dwFlags = flags;
|
||||||
|
config.nDefaultButton = default_id ? (kIDStart + default_id) : 0;
|
||||||
|
|
||||||
// TaskDialogIndirect doesn't allow empty name, if we set empty title it
|
// TaskDialogIndirect doesn't allow empty name, if we set empty title it
|
||||||
// will show "electron.exe" in title.
|
// will show "electron.exe" in title.
|
||||||
|
@ -156,6 +158,7 @@ void RunMessageBoxInNewThread(base::Thread* thread,
|
||||||
NativeWindow* parent,
|
NativeWindow* parent,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
@ -163,8 +166,8 @@ void RunMessageBoxInNewThread(base::Thread* thread,
|
||||||
const std::string& detail,
|
const std::string& detail,
|
||||||
const gfx::ImageSkia& icon,
|
const gfx::ImageSkia& icon,
|
||||||
const MessageBoxCallback& callback) {
|
const MessageBoxCallback& callback) {
|
||||||
int result = ShowMessageBox(parent, type, buttons, cancel_id, options, title,
|
int result = ShowMessageBox(parent, type, buttons, default_id,
|
||||||
message, detail, icon);
|
cancel_id, options, title, message, detail, icon);
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
|
content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
|
||||||
content::BrowserThread::DeleteSoon(
|
content::BrowserThread::DeleteSoon(
|
||||||
|
@ -176,6 +179,7 @@ void RunMessageBoxInNewThread(base::Thread* thread,
|
||||||
int ShowMessageBox(NativeWindow* parent,
|
int ShowMessageBox(NativeWindow* parent,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
@ -194,6 +198,7 @@ int ShowMessageBox(NativeWindow* parent,
|
||||||
return ShowMessageBoxUTF16(hwnd_parent,
|
return ShowMessageBoxUTF16(hwnd_parent,
|
||||||
type,
|
type,
|
||||||
utf16_buttons,
|
utf16_buttons,
|
||||||
|
default_id,
|
||||||
cancel_id,
|
cancel_id,
|
||||||
options,
|
options,
|
||||||
base::UTF8ToUTF16(title),
|
base::UTF8ToUTF16(title),
|
||||||
|
@ -205,6 +210,7 @@ int ShowMessageBox(NativeWindow* parent,
|
||||||
void ShowMessageBox(NativeWindow* parent,
|
void ShowMessageBox(NativeWindow* parent,
|
||||||
MessageBoxType type,
|
MessageBoxType type,
|
||||||
const std::vector<std::string>& buttons,
|
const std::vector<std::string>& buttons,
|
||||||
|
int default_id,
|
||||||
int cancel_id,
|
int cancel_id,
|
||||||
int options,
|
int options,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
|
@ -224,13 +230,13 @@ void ShowMessageBox(NativeWindow* parent,
|
||||||
unretained->message_loop()->PostTask(
|
unretained->message_loop()->PostTask(
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
|
base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
|
||||||
parent, type, buttons, cancel_id, options, title, message,
|
parent, type, buttons, default_id,
|
||||||
detail, icon, callback));
|
cancel_id, options, title, message, detail, icon, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
||||||
ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, 0, 0, L"Error", title,
|
ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, -1, 0, 0, L"Error",
|
||||||
content, gfx::ImageSkia());
|
title, content, gfx::ImageSkia());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -87,6 +87,8 @@ will be passed via `callback(filename)`
|
||||||
`"warning"`. On Windows, "question" displays the same icon as "info", unless
|
`"warning"`. On Windows, "question" displays the same icon as "info", unless
|
||||||
you set an icon using the "icon" option.
|
you set an icon using the "icon" option.
|
||||||
* `buttons` Array - Array of texts for buttons.
|
* `buttons` Array - Array of texts for buttons.
|
||||||
|
* `defaultId` Integer - Index of the button in the buttons array which will
|
||||||
|
be selected by default when the message box opens.
|
||||||
* `title` String - Title of the message box, some platforms will not show it.
|
* `title` String - Title of the message box, some platforms will not show it.
|
||||||
* `message` String - Content of the message box.
|
* `message` String - Content of the message box.
|
||||||
* `detail` String - Extra information of the message.
|
* `detail` String - Extra information of the message.
|
||||||
|
|
Loading…
Reference in a new issue