Skip to content

Commit 003d516

Browse files
authored
DesktopGL implementation for MessageBox.Show() (MonoGame#8720)
Here's an implementation of ```MessageBox.Show()``` for DesktopGL. All platforms should be supported now.
1 parent b922b14 commit 003d516

File tree

3 files changed

+112
-1
lines changed

3 files changed

+112
-1
lines changed

MonoGame.Framework/MonoGame.Framework.DesktopGL.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
<Compile Include="Platform\Input\KeysHelper.cs" />
7575
<Compile Include="Platform\Input\Mouse.SDL.cs" />
7676
<Compile Include="Platform\Input\MouseCursor.SDL.cs" />
77-
<Compile Include="Platform\Input\MessageBox.Default.cs" />
77+
<Compile Include="Platform\Input\MessageBox.SDL.cs" />
7878
<Compile Include="Platform\Graphics\GraphicsContext.SDL.cs" />
7979
<Compile Include="Platform\Graphics\OpenGL.SDL.cs" />
8080
<Compile Include="Platform\Graphics\WindowInfo.SDL.cs" />
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using MonoGame.Framework.Utilities;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Microsoft.Xna.Framework.Input
9+
{
10+
public static partial class MessageBox
11+
{
12+
private static TaskCompletionSource<int?> _tcs;
13+
14+
private static Task<int?> PlatformShow(string title, string description, List<string> buttons)
15+
{
16+
_tcs = new TaskCompletionSource<int?>();
17+
18+
Sdl.Window.MessageBoxData data = new Sdl.Window.MessageBoxData();
19+
data.flags = 0;
20+
data.title = title;
21+
data.message = description;
22+
data.numbuttons = 0;
23+
data.buttons = IntPtr.Zero;
24+
data.colorScheme = IntPtr.Zero;
25+
26+
if (buttons != null &&
27+
buttons.Count > 0)
28+
{
29+
Sdl.Window.MessageBoxButtonData[] buttonData = new Sdl.Window.MessageBoxButtonData[buttons.Count];
30+
31+
for (int i = 0; i < buttons.Count; i++)
32+
{
33+
// We need to reverse button order on Windows only
34+
// SDL3 has a flag to reverse that but SDL2 doesn't
35+
int reverseIndex = (CurrentPlatform.OS == OS.Windows ? buttons.Count - i - 1 : i);
36+
37+
buttonData[i] = new Sdl.Window.MessageBoxButtonData();
38+
buttonData[i].flags = 0;
39+
buttonData[i].buttonid = reverseIndex;
40+
buttonData[i].text = IntPtr.Zero;
41+
42+
if (buttons[i] != null)
43+
{
44+
// convert to C string pointer data because we need to marshal a struct array
45+
byte[] bytes = Encoding.UTF8.GetBytes(buttons[reverseIndex]);
46+
IntPtr mem = Marshal.AllocHGlobal(bytes.Length + 1);
47+
Marshal.Copy(bytes, 0, mem, bytes.Length);
48+
unsafe
49+
{
50+
((byte*)mem)[bytes.Length] = 0;
51+
}
52+
53+
buttonData[i].text = mem;
54+
}
55+
}
56+
57+
data.numbuttons = buttons.Count;
58+
59+
// convert the struct array to pointer
60+
unsafe
61+
{
62+
fixed (Sdl.Window.MessageBoxButtonData* buttonsPtr = &buttonData[0])
63+
{
64+
data.buttons = (IntPtr)buttonsPtr;
65+
}
66+
}
67+
}
68+
69+
int result = -1;
70+
71+
int error = Sdl.Window.ShowMessageBox(ref data, out result);
72+
73+
if (error == 0)
74+
_tcs.SetResult(result);
75+
else
76+
_tcs.SetResult(-1);
77+
78+
return _tcs.Task;
79+
}
80+
81+
private static void PlatformCancel(int? result)
82+
{
83+
if (_tcs != null)
84+
_tcs.SetResult(result);
85+
}
86+
}
87+
}

MonoGame.Framework/Platform/SDL/SDL2.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,30 @@ public static void SetTitle(IntPtr handle, string title)
491491
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
492492
public delegate int d_sdl_getwindowborderssize(IntPtr window, out int top, out int left, out int right, out int bottom);
493493
public static d_sdl_getwindowborderssize GetBorderSize = FuncLoader.LoadFunction<d_sdl_getwindowborderssize>(NativeLibrary, "SDL_GetWindowBordersSize");
494+
495+
[StructLayout(LayoutKind.Sequential)]
496+
public struct MessageBoxData
497+
{
498+
public uint flags;
499+
public IntPtr window;
500+
public string title;
501+
public string message;
502+
public int numbuttons;
503+
public IntPtr buttons;
504+
public IntPtr colorScheme;
505+
}
506+
507+
[StructLayout(LayoutKind.Sequential)]
508+
public struct MessageBoxButtonData
509+
{
510+
public uint flags;
511+
public int buttonid;
512+
public IntPtr text;
513+
}
514+
515+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
516+
public delegate int d_sdl_showmessagebox(ref MessageBoxData messageboxdata, out int buttonid);
517+
public static d_sdl_showmessagebox ShowMessageBox = FuncLoader.LoadFunction<d_sdl_showmessagebox>(NativeLibrary, "SDL_ShowMessageBox");
494518
}
495519

496520
public static class Display

0 commit comments

Comments
 (0)