diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj old mode 100644 new mode 100755 diff --git a/include/SDL_messagebox.h b/include/SDL_messagebox.h index e34b55477..afa5a13d5 100644 --- a/include/SDL_messagebox.h +++ b/include/SDL_messagebox.h @@ -36,9 +36,11 @@ extern "C" { */ typedef enum { - SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ - SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ - SDL_MESSAGEBOX_INFORMATION = 0x00000040 /**< informational dialog */ + SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ + SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ + SDL_MESSAGEBOX_INFORMATION = 0x00000040, /**< informational dialog */ + SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT = 0x00000080, /**< buttons placed left to right */ + SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT = 0x00000100, /**< buttons placed right to left */ } SDL_MessageBoxFlags; /** diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 967458707..02b9fd4f3 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -2380,11 +2380,19 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu button_texts = (*env)->NewObjectArray(env, messageboxdata->numbuttons, clazz, NULL); for (i = 0; i < messageboxdata->numbuttons; ++i) { - temp = messageboxdata->buttons[i].flags; + const SDL_MessageBoxButtonData *sdlButton; + + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; + } else { + sdlButton = &messageboxdata->buttons[i]; + } + + temp = sdlButton->flags; (*env)->SetIntArrayRegion(env, button_flags, i, 1, &temp); - temp = messageboxdata->buttons[i].buttonid; + temp = sdlButton->buttonid; (*env)->SetIntArrayRegion(env, button_ids, i, 1, &temp); - text = (*env)->NewStringUTF(env, messageboxdata->buttons[i].text); + text = (*env)->NewStringUTF(env, sdlButton->text); (*env)->SetObjectArrayElement(env, button_texts, i, text); (*env)->DeleteLocalRef(env, text); } diff --git a/src/video/cocoa/SDL_cocoamessagebox.m b/src/video/cocoa/SDL_cocoamessagebox.m index 36d4944b5..c3fbbbe11 100644 --- a/src/video/cocoa/SDL_cocoamessagebox.m +++ b/src/video/cocoa/SDL_cocoamessagebox.m @@ -112,10 +112,19 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons; int i; for (i = 0; i < messageboxdata->numbuttons; ++i) { - NSButton *button = [alert addButtonWithTitle:[NSString stringWithUTF8String:buttons[i].text]]; - if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { + const SDL_MessageBoxButtonData *sdlButton; + NSButton *button; + + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; + } else { + sdlButton = &messageboxdata->buttons[i]; + } + + button = [alert addButtonWithTitle:[NSString stringWithUTF8String:sdlButton->text]]; + if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { [button setKeyEquivalent:@"\r"]; - } else if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { + } else if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { [button setKeyEquivalent:@"\033"]; } else { [button setKeyEquivalent:@""]; @@ -132,6 +141,9 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) NSInteger clicked = presenter->clicked; if (clicked >= NSAlertFirstButtonReturn) { clicked -= NSAlertFirstButtonReturn; + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + clicked = messageboxdata->numbuttons - 1 - clicked; + } *buttonid = buttons[clicked].buttonid; } else { returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked); diff --git a/src/video/uikit/SDL_uikitmessagebox.m b/src/video/uikit/SDL_uikitmessagebox.m index b14a3c019..7480f645c 100644 --- a/src/video/uikit/SDL_uikitmessagebox.m +++ b/src/video/uikit/SDL_uikitmessagebox.m @@ -73,15 +73,22 @@ UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, in for (i = 0; i < messageboxdata->numbuttons; i++) { UIAlertAction *action; UIAlertActionStyle style = UIAlertActionStyleDefault; + const SDL_MessageBoxButtonData *sdlButton; - if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; + } else { + sdlButton = &messageboxdata->buttons[i]; + } + + if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { style = UIAlertActionStyleCancel; } - action = [UIAlertAction actionWithTitle:@(buttons[i].text) + action = [UIAlertAction actionWithTitle:@(sdlButton->text) style:style handler:^(UIAlertAction *action) { - clickedindex = i; + clickedindex = (int)(sdlButton - messageboxdata->buttons); }]; [alert addAction:action]; } @@ -150,7 +157,13 @@ UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *but alert.message = @(messageboxdata->message); for (i = 0; i < messageboxdata->numbuttons; i++) { - [alert addButtonWithTitle:@(buttons[i].text)]; + const SDL_MessageBoxButtonData *sdlButton; + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; + } else { + sdlButton = &messageboxdata->buttons[i]; + } + [alert addButtonWithTitle:@(sdlButton->text)]; } delegate.clickedIndex = &clickedindex; @@ -161,6 +174,9 @@ UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *but alert.delegate = nil; + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + clickedindex = messageboxdata->numbuttons - 1 - clickedindex; + } *buttonid = messageboxdata->buttons[clickedindex].buttonid; return YES; #else diff --git a/src/video/windows/SDL_windowsmessagebox.c b/src/video/windows/SDL_windowsmessagebox.c index e5ddd39c4..7615ee6e9 100644 --- a/src/video/windows/SDL_windowsmessagebox.c +++ b/src/video/windows/SDL_windowsmessagebox.c @@ -367,7 +367,7 @@ static SDL_bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int if (dialog->numbuttons == 0) { style |= WS_GROUP; } - return AddDialogControl(dialog, DLGITEMTYPEBUTTON, style, 0, x, y, w, h, IDBUTTONINDEX0 + dialog->numbuttons, text, 0); + return AddDialogControl(dialog, DLGITEMTYPEBUTTON, style, 0, x, y, w, h, id, text, 0); } static void FreeDialogData(WIN_DialogData *dialog) @@ -708,23 +708,36 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) /* Align the buttons to the right/bottom. */ x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons; y = Size.cy - ButtonHeight - ButtonMargin; - for (i = messageboxdata->numbuttons - 1; i >= 0; --i) { + for (i = 0; i < messageboxdata->numbuttons; i++) { SDL_bool isdefault = SDL_FALSE; const char *buttontext; + const SDL_MessageBoxButtonData *sdlButton; - if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { + /* We always have to create the dialog buttons from left to right + * so that the tab order is correct. Select the info to use + * depending on which order was requested. */ + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT) { + sdlButton = &messageboxdata->buttons[i]; + } else { + sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; + } + + if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { defbuttoncount++; if (defbuttoncount == 1) { isdefault = SDL_TRUE; } } - buttontext = EscapeAmpersands(&escape, &escapesize, buttons[i].text); - if (buttontext == NULL || !AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttontext, buttons[i].buttonid, isdefault)) { + buttontext = EscapeAmpersands(&escape, &escapesize, sdlButton->text); + /* Make sure to provide the correct ID to keep buttons indexed in the + * same order as how they are in messageboxdata. */ + if (buttontext == NULL || !AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttontext, IDBUTTONINDEX0 + (int)(sdlButton - messageboxdata->buttons), isdefault)) { FreeDialogData(dialog); SDL_free(ampescape); return -1; } + x += ButtonWidth + ButtonMargin; } SDL_free(ampescape); @@ -737,7 +750,7 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc, (LPARAM)messageboxdata); if (result >= IDBUTTONINDEX0 && result - IDBUTTONINDEX0 < messageboxdata->numbuttons) { - *buttonid = messageboxdata->buttons[(messageboxdata->numbuttons - 1) - (result - IDBUTTONINDEX0)].buttonid; + *buttonid = messageboxdata->buttons[result - IDBUTTONINDEX0].buttonid; retval = 0; } else if (result == IDCLOSED) { /* Dialog window closed by user or system. */ @@ -841,15 +854,16 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) for (i = 0; i < messageboxdata->numbuttons; i++) { const char *buttontext; - pButton = &pButtons[messageboxdata->numbuttons-1-i]; + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT) { + pButton = &pButtons[i]; + } else { + pButton = &pButtons[messageboxdata->numbuttons - 1 - i]; + } if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { nCancelButton = messageboxdata->buttons[i].buttonid; - pButton->nButtonID = 2; + pButton->nButtonID = IDCANCEL; } else { - pButton->nButtonID = messageboxdata->buttons[i].buttonid + 1; - if (pButton->nButtonID >= 2) { - pButton->nButtonID++; - } + pButton->nButtonID = IDBUTTONINDEX0 + i; } buttontext = EscapeAmpersands(&escape, &escapesize, messageboxdata->buttons[i].text); if (buttontext == NULL) { @@ -886,12 +900,12 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) /* Check the Task Dialog was successful and give the result */ if (SUCCEEDED(hr)) { - if (nButton == 2) { + if (nButton == IDCANCEL) { *buttonid = nCancelButton; - } else if (nButton > 2) { - *buttonid = nButton-1-1; + } else if (nButton >= IDBUTTONINDEX0 && nButton < IDBUTTONINDEX0 + messageboxdata->numbuttons) { + *buttonid = messageboxdata->buttons[nButton - IDBUTTONINDEX0].buttonid; } else { - *buttonid = nButton-1; + *buttonid = -1; } return 0; } diff --git a/src/video/winrt/SDL_winrtmessagebox.cpp b/src/video/winrt/SDL_winrtmessagebox.cpp index 34e2228a0..3c7289144 100644 --- a/src/video/winrt/SDL_winrtmessagebox.cpp +++ b/src/video/winrt/SDL_winrtmessagebox.cpp @@ -75,13 +75,19 @@ WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) MessageDialog ^ dialog = ref new MessageDialog(WINRT_UTF8ToPlatformString(messageboxdata->message)); dialog->Title = WINRT_UTF8ToPlatformString(messageboxdata->title); for (int i = 0; i < messageboxdata->numbuttons; ++i) { - UICommand ^ button = ref new UICommand(WINRT_UTF8ToPlatformString(messageboxdata->buttons[i].text)); - button->Id = safe_cast(i); + const SDL_MessageBoxButtonData *sdlButton; + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; + } else { + sdlButton = &messageboxdata->buttons[i]; + } + UICommand ^ button = ref new UICommand(WINRT_UTF8ToPlatformString(sdlButton->text)); + button->Id = safe_cast(sdlButton - messageboxdata->buttons); dialog->Commands->Append(button); - if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { + if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { dialog->CancelCommandIndex = i; } - if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { + if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { dialog->DefaultCommandIndex = i; } } diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c index adf682164..dd234e63e 100644 --- a/src/video/x11/SDL_x11messagebox.c +++ b/src/video/x11/SDL_x11messagebox.c @@ -334,7 +334,11 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data ) data->dialog_height = IntMax( data->dialog_height, ybuttons + 2 * button_height ); /* Location for first button. */ - x = ( data->dialog_width - width_of_buttons ) / 2; + if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) { + x = data->dialog_width - ( data->dialog_width - width_of_buttons ) / 2 - ( button_width + button_spacing ); + } else { + x = ( data->dialog_width - width_of_buttons ) / 2; + } y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2; for ( i = 0; i < data->numbuttons; i++ ) { @@ -349,7 +353,11 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data ) data->buttonpos[ i ].y = y + ( button_height - button_text_height - 1 ) / 2 + button_text_height; /* Scoot over for next button. */ - x += button_width + button_spacing; + if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) { + x -= button_width + button_spacing; + } else { + x += button_width + button_spacing; + } } }