Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions Assets/NativeDialogSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,41 @@
using System.Collections;
using NativeDialog;

/// <summary>
/// Sample component demonstrating the usage of native dialog functionality.
/// Provides various examples of showing select and submit dialogs with different configurations.
/// </summary>
public class NativeDialogSample : MonoBehaviour
{
/// <summary>
/// Label text for the positive/confirm button in dialogs.
/// </summary>
[SerializeField] private string decideLabel = "Decide";

/// <summary>
/// Label text for the negative/reject button in dialogs.
/// </summary>
[SerializeField] private string cancelLabel = "Cancel";

/// <summary>
/// Label text for the close button in submit-only dialogs.
/// </summary>
[SerializeField] private string closeLabel = "Close";

/// <summary>
/// Initializes the dialog labels when the component starts.
/// </summary>
private void Start()
{
DialogManager.SetLabel(decideLabel, cancelLabel, closeLabel);
}

#region Invoked from Unity GUI

/// <summary>
/// Shows a simple selection dialog with OK/Cancel buttons.
/// Logs the user's choice to the console.
/// </summary>
public void ShowSelectDialog()
{
const string message = "A simple select dialog";
Expand All @@ -24,6 +46,10 @@ public void ShowSelectDialog()
});
}

/// <summary>
/// Shows a selection dialog with both title and message.
/// Useful for providing more context to the user.
/// </summary>
public void ShowSelectDialogWithTitle()
{
const string title = "A title";
Expand All @@ -34,6 +60,10 @@ public void ShowSelectDialogWithTitle()
});
}

/// <summary>
/// Shows a submit-only dialog with a single OK button.
/// Used for notifications or acknowledgments.
/// </summary>
public void ShowSubmitDialog()
{
const string message = "A simple submit dialog";
Expand All @@ -43,6 +73,10 @@ public void ShowSubmitDialog()
});
}

/// <summary>
/// Shows a submit dialog with both title and message.
/// Provides a more detailed notification to the user.
/// </summary>
public void ShowSubmitDialogWithTitle()
{
const string title = "A title";
Expand All @@ -53,6 +87,10 @@ public void ShowSubmitDialogWithTitle()
});
}

/// <summary>
/// Shows a dialog that automatically dismisses after 3 seconds.
/// Demonstrates how to programmatically close dialogs.
/// </summary>
public void ShowDialogWithAutoDismiss()
{
const string message = "A dialog with auto dismiss";
Expand Down
59 changes: 52 additions & 7 deletions Packages/com.github.asus4.nativedialog/Runtime/DialogManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
namespace NativeDialog
{
/// <summary>
/// Popup Native Dialog
/// Manages Native Dialog popups across different platforms.
/// Provides a unified interface for showing native select and submit dialogs on iOS, Android, and Unity Editor.
/// </summary>
public sealed class DialogManager : MonoBehaviour, IDialogReceiver
{

#region Singleton
private static DialogManager instance;

/// <summary>
/// Gets the singleton instance of DialogManager.
/// Creates a new instance if one doesn't exist.
/// </summary>
public static DialogManager Instance
{
get
Expand All @@ -33,10 +39,11 @@ public static DialogManager Instance

#region Members
private Dictionary<int, Action<bool>> callbacks;

private IDialog dialog;
#endregion

#region Lyfecycles
#region Lifecycles
private void Awake()
{
if (instance == null)
Expand Down Expand Up @@ -65,9 +72,7 @@ private void Awake()
private IDialog CreateDialog()
{
#if UNITY_EDITOR
var mock = gameObject.AddComponent<DialogMock>();
mock.Initialize(this, true);
return mock;
return new DialogEditor(this);
#elif UNITY_ANDROID
return new DialogAndroid();
#elif UNITY_IOS
Expand All @@ -92,39 +97,78 @@ private void OnDestroy()
}
#endregion

#region Public Methods

/// <summary>
/// Sets the button labels for all future dialogs.
/// </summary>
/// <param name="decide">Label for the positive/confirm button</param>
/// <param name="cancel">Label for the negative/cancel button</param>
/// <param name="close">Label for the close button in submit dialogs</param>
public static void SetLabel(string decide, string cancel, string close)
{
Instance.dialog.SetLabel(decide, cancel, close);
}

/// <summary>
/// Shows a selection dialog with OK/Cancel buttons.
/// </summary>
/// <param name="message">The message to display</param>
/// <param name="callback">Callback invoked with true for OK, false for Cancel</param>
/// <returns>Dialog ID that can be used to dismiss the dialog</returns>
public static int ShowSelect(string message, Action<bool> callback)
{
int id = Instance.dialog.ShowSelect(message);
Instance.callbacks.Add(id, callback);
return id;
}

/// <summary>
/// Shows a selection dialog with title and OK/Cancel buttons.
/// </summary>
/// <param name="title">The dialog title</param>
/// <param name="message">The message to display</param>
/// <param name="callback">Callback invoked with true for OK, false for Cancel</param>
/// <returns>Dialog ID that can be used to dismiss the dialog</returns>
public static int ShowSelect(string title, string message, Action<bool> callback)
{
int id = Instance.dialog.ShowSelect(title, message);
Instance.callbacks.Add(id, callback);
return id;
}

/// <summary>
/// Shows a submit dialog with only an OK button.
/// </summary>
/// <param name="message">The message to display</param>
/// <param name="callback">Callback invoked when the dialog is closed</param>
/// <returns>Dialog ID that can be used to dismiss the dialog</returns>
public static int ShowSubmit(string message, Action<bool> callback)
{
int id = Instance.dialog.ShowSubmit(message);
Instance.callbacks.Add(id, callback);
return id;
}

public static int ShowSubmit(string title, string message, Action<bool> del)
/// <summary>
/// Shows a submit dialog with title and only an OK button.
/// </summary>
/// <param name="title">The dialog title</param>
/// <param name="message">The message to display</param>
/// <param name="callback">Callback invoked when the dialog is closed</param>
/// <returns>Dialog ID that can be used to dismiss the dialog</returns>
public static int ShowSubmit(string title, string message, Action<bool> callback)
{
int id = Instance.dialog.ShowSubmit(title, message);
Instance.callbacks.Add(id, del);
Instance.callbacks.Add(id, callback);
return id;
}

/// <summary>
/// Programmatically dismisses a dialog.
/// Invokes the callback with false (cancelled).
/// </summary>
/// <param name="id">The ID of the dialog to dismiss</param>
public static void Dismiss(int id)
{
Instance.dialog.Dismiss(id);
Expand All @@ -141,6 +185,7 @@ public static void Dismiss(int id)
}
}

#endregion // Public Methods

#region Invoked from Native Plugin
public void OnSubmit(string idStr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace NativeDialog
{
/// <summary>
/// Android-specific implementation of native dialogs using AndroidJavaClass.
/// </summary>
internal sealed class DialogAndroid : IDialog
{
private readonly AndroidJavaClass cls;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#if UNITY_EDITOR
using System.Collections.Generic;
using UnityEditor;

namespace NativeDialog
{
/// <summary>
/// Mock implementation of dialogs for Unity Editor.
/// </summary>
internal sealed class DialogEditor : IDialog
{
private string decideLabel = "YES";
private string cancelLabel = "NO";
private string closeLabel = "CLOSE";
private int currentId = 0;
private IDialogReceiver receiver;
private readonly Dictionary<int, bool> pendingDialogs = new Dictionary<int, bool>();

public DialogEditor(IDialogReceiver receiver)
{
this.receiver = receiver;
}

public void Dispose()
{
pendingDialogs.Clear();
receiver = null;
}

public void SetLabel(string decide, string cancel, string close)
{
decideLabel = decide;
cancelLabel = cancel;
closeLabel = close;
}

public int ShowSelect(string message)
{
int id = ++currentId;
EditorApplication.delayCall += () => ShowSelectDialog(id, null, message);
return id;
}

public int ShowSelect(string title, string message)
{
int id = ++currentId;
EditorApplication.delayCall += () => ShowSelectDialog(id, title, message);
return id;
}

public int ShowSubmit(string message)
{
int id = ++currentId;
EditorApplication.delayCall += () => ShowSubmitDialog(id, null, message);
return id;
}

public int ShowSubmit(string title, string message)
{
int id = ++currentId;
EditorApplication.delayCall += () => ShowSubmitDialog(id, title, message);
return id;
}

public void Dismiss(int id)
{
UnityEngine.Debug.LogWarning($"Dismiss is not supported in Editor mode. ID: {id}");
if (pendingDialogs.ContainsKey(id))
{
pendingDialogs.Remove(id);
}
}

private void ShowSelectDialog(int id, string title, string message)
{
if (!pendingDialogs.ContainsKey(id))
{
pendingDialogs[id] = true;
}
else if (!pendingDialogs[id])
{
return;
}

bool result;
if (string.IsNullOrEmpty(title))
{
result = EditorUtility.DisplayDialog("", message, decideLabel, cancelLabel);
}
else
{
result = EditorUtility.DisplayDialog(title, message, decideLabel, cancelLabel);
}

if (pendingDialogs.ContainsKey(id))
{
pendingDialogs.Remove(id);
if (result)
{
receiver?.OnSubmit(id.ToString());
}
else
{
receiver?.OnCancel(id.ToString());
}
}
}

private void ShowSubmitDialog(int id, string title, string message)
{
if (!pendingDialogs.ContainsKey(id))
{
pendingDialogs[id] = true;
}
else if (!pendingDialogs[id])
{
return;
}

if (string.IsNullOrEmpty(title))
{
EditorUtility.DisplayDialog("", message, closeLabel);
}
else
{
EditorUtility.DisplayDialog(title, message, closeLabel);
}

if (pendingDialogs.ContainsKey(id))
{
pendingDialogs.Remove(id);
receiver?.OnSubmit(id.ToString());
}
}
}
}
#endif

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace NativeDialog
{
/// <summary>
/// iOS-specific implementation of native dialogs using DllImport to call native methods.
/// </summary>
internal sealed class DialogIOS : IDialog
{
public void Dispose()
Expand Down
Loading