Skip to content

Commit 8a076dc

Browse files
committed
Confirmation and message implementation
1 parent c52dd44 commit 8a076dc

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

AssetRipper.NativeDialogs/ConfirmationDialog.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Runtime.Versioning;
1+
using System.ComponentModel;
2+
using System.Runtime.Versioning;
3+
using TerraFX.Interop.Windows;
24

35
namespace AssetRipper.NativeDialogs;
46

@@ -37,7 +39,34 @@ public static class ConfirmationDialog
3739
[SupportedOSPlatform("windows")]
3840
private unsafe static Task<bool?> ConfirmWindows(string message, string trueLabel, string falseLabel)
3941
{
40-
return Task.FromResult<bool?>(null);
42+
int statusCode;
43+
fixed (char* messagePtr = message)
44+
{
45+
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxw
46+
statusCode = Windows.MessageBoxW(
47+
default, // No owner window.
48+
messagePtr, // Message text.
49+
null, // Title.
50+
MB.MB_OKCANCEL | MB.MB_ICONQUESTION); // OK button and information icon.
51+
}
52+
53+
if (statusCode == 0)
54+
{
55+
int errorCode = unchecked((int)Windows.GetLastError());
56+
throw new Win32Exception(errorCode, "Failed to show message dialog.");
57+
}
58+
else if (statusCode is Windows.IDYES or Windows.IDOK)
59+
{
60+
return Task.FromResult<bool?>(true);
61+
}
62+
else if (statusCode is Windows.IDNO or Windows.IDCANCEL)
63+
{
64+
return Task.FromResult<bool?>(false);
65+
}
66+
else
67+
{
68+
throw new($"Unexpected status code {statusCode} from {nameof(Windows.MessageBoxW)}.");
69+
}
4170
}
4271

4372
[SupportedOSPlatform("macos")]
@@ -72,7 +101,20 @@ public static class ConfirmationDialog
72101
Gtk.Application.Init(); // spins a main loop
73102
try
74103
{
75-
result = null;
104+
using Gtk.MessageDialog md = new(
105+
null,
106+
Gtk.DialogFlags.Modal,
107+
Gtk.MessageType.Info,
108+
Gtk.ButtonsType.Ok,
109+
message
110+
);
111+
int response = md.Run();
112+
result = response switch
113+
{
114+
(int)Gtk.ResponseType.Ok or (int)Gtk.ResponseType.Yes => true,
115+
(int)Gtk.ResponseType.Cancel or (int)Gtk.ResponseType.No => false,
116+
_ => throw new($"Unexpected response type: {response}"),
117+
};
76118
}
77119
finally
78120
{

AssetRipper.NativeDialogs/MessageDialog.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Runtime.Versioning;
1+
using System.ComponentModel;
2+
using System.Runtime.Versioning;
3+
using TerraFX.Interop.Windows;
24

35
namespace AssetRipper.NativeDialogs;
46

@@ -32,6 +34,27 @@ public static Task Message(string message)
3234
[SupportedOSPlatform("windows")]
3335
private unsafe static Task MessageWindows(string message)
3436
{
37+
int statusCode;
38+
fixed (char* messagePtr = message)
39+
{
40+
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxw
41+
statusCode = Windows.MessageBoxW(
42+
default, // No owner window.
43+
messagePtr, // Message text.
44+
null, // Title.
45+
MB.MB_OK | MB.MB_ICONINFORMATION); // OK button and information icon.
46+
}
47+
48+
if (statusCode == 0)
49+
{
50+
int errorCode = unchecked((int)Windows.GetLastError());
51+
throw new Win32Exception(errorCode, "Failed to show message dialog.");
52+
}
53+
else if (statusCode != Windows.IDOK)
54+
{
55+
throw new($"Unexpected status code {statusCode} from {nameof(Windows.MessageBoxW)}.");
56+
}
57+
3558
return Task.CompletedTask;
3659
}
3760

@@ -50,6 +73,14 @@ private static Task MessageLinux(string message)
5073
Gtk.Application.Init(); // spins a main loop
5174
try
5275
{
76+
using Gtk.MessageDialog md = new(
77+
null,
78+
Gtk.DialogFlags.Modal,
79+
Gtk.MessageType.Info,
80+
Gtk.ButtonsType.Ok,
81+
message
82+
);
83+
md.Run();
5384
}
5485
finally
5586
{

0 commit comments

Comments
 (0)