// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities.Solvers;
using System;
using System.Collections;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.UI
{
public abstract class Dialog : MonoBehaviour
{
///
/// The current state of the Dialog.
///
public DialogState State { get; set; } = DialogState.Uninitialized;
///
/// Called after user has clicked a button and the dialog has finished closing
///
public Action OnClosed;
protected DialogResult result;
///
/// Can be used to monitor result instead of events
///
public DialogResult Result => result;
protected void Launch(DialogResult newResult)
{
if (State != DialogState.Uninitialized)
{
return;
}
result = newResult;
StartCoroutine(RunDialogOverTime());
}
///
/// Opens dialog, waits for input, then closes
///
protected IEnumerator RunDialogOverTime()
{
// Create buttons and set up message
GenerateButtons();
SetTitleAndMessage();
FinalizeLayout();
// Open dialog
State = DialogState.Opening;
yield return StartCoroutine(OpenDialog());
State = DialogState.WaitingForInput;
// Wait for input
while (State == DialogState.WaitingForInput)
{
UpdateDialog();
yield return null;
}
// Close dialog
State = DialogState.Closing;
yield return StartCoroutine(CloseDialog());
State = DialogState.Closed;
// Callback
OnClosed?.Invoke(result);
// Wait a moment to give scripts a chance to respond
yield return null;
// Destroy ourselves
Destroy(gameObject);
yield break;
}
///
/// Opens the dialog - state must be set to WaitingForInput afterwards
/// Overridden in inherited class.
/// Perform any change here that you'd like to have when the dialog opened.
///
protected virtual IEnumerator OpenDialog()
{
yield break;
}
///
/// Closes the dialog - state must be set to Closed afterwards
///
protected virtual IEnumerator CloseDialog()
{
yield break;
}
///
/// Perform any updates (animation, tagalong, etc) here
/// This will be called every frame while waiting for input
///
protected virtual void UpdateDialog()
{
return;
}
///
/// Generates buttons - Must parent them under buttonParent!
///
protected abstract void GenerateButtons();
///
/// This is called after the buttons are generated and
/// the title and message have been set.
/// Perform here any operations that you'd like
/// Lays out the buttons on the dialog
/// E.g. using an ObjectCollection
///
protected abstract void FinalizeLayout();
///
/// Set the title and message using the result
/// E.g. using TextMesh components
///
protected abstract void SetTitleAndMessage();
///
/// Function to destroy the Dialog.
///
public abstract void DismissDialog();
///
/// Instantiates a dialog and passes it a result
///
/// Dialog prefab
/// DialogResult class object which contains information such as title and description text
public static Dialog Open(GameObject dialogPrefab, DialogResult result)
{
GameObject dialogGo = GameObject.Instantiate(dialogPrefab) as GameObject;
Dialog dialog = dialogGo.GetComponent