Merge pull request #4029 from leethomas/show-message-box-default-button

Show message box default button
This commit is contained in:
Cheng Zhao 2016-01-11 20:58:03 +08:00
commit edcd34d4ce
7 changed files with 60 additions and 22 deletions

View file

@ -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);
} }
} }

View file

@ -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,

View file

@ -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,

View file

@ -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();

View file

@ -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];

View file

@ -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

View file

@ -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.