GUIPopup.cs 4.72 KB
Newer Older
BlackAngle233's avatar
BlackAngle233 committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//================================================================================================================================
//
//  Copyright (c) 2015-2021 VisionStar Information Technology (Shanghai) Co., Ltd. All Rights Reserved.
//  EasyAR is the registered trademark or trademark of VisionStar Information Technology (Shanghai) Co., Ltd in China
//  and other countries for the augmented reality technology developed by VisionStar Information Technology (Shanghai) Co., Ltd.
//
//================================================================================================================================

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace easyar
{
    /// <summary>
    /// <para xml:lang="en">Popup for message notification. The popup action can be globally controlled using <see cref="EasyARController.ShowPopupMessage"/>.</para>
    /// <para xml:lang="zh">消息提示弹窗。是否需要显示弹窗可以通过<see cref="EasyARController.ShowPopupMessage"/>来进行全局控制。</para>
    /// </summary>
    public class GUIPopup : MonoBehaviour
    {
        private static GUIPopup popup;
        private readonly Queue<KeyValuePair<string, float>> messageQueue = new Queue<KeyValuePair<string, float>>();
        private bool isShowing;
        private bool isDisappearing;
        private GUISkin skin;

        private void Start()
        {
            skin = Instantiate(Resources.Load<GUISkin>("EasyAR/GUISkin/GUIPopup"));
            StartCoroutine(ShowMessage());
        }

        private void OnDestroy()
        {
            if (skin)
            {
                Destroy(skin);
            }
        }

        /// <summary>
        /// <para xml:lang="en">Add one message and its duration for display.</para>
        /// <para xml:lang="zh">添加一条要显示的消息及时长。</para>
        /// </summary>
        public static void EnqueueMessage(string message, float seconds)
        {
            if (EasyARController.Instance && !EasyARController.Instance.ShowPopupMessage)
            {
                Debug.Log(message);
                return;
            }

            if (popup == null)
            {
                var go = new GameObject("MessagePopup");
                popup = go.AddComponent<GUIPopup>();
            }
            popup.messageQueue.Enqueue(new KeyValuePair<string, float>(message, seconds));
        }

        private IEnumerator ShowMessage()
        {
            while (true)
            {
                if (EasyARController.Instance && !EasyARController.Instance.ShowPopupMessage)
                {
                    while (messageQueue.Count > 0)
                    {
                        var message = messageQueue.Dequeue();
                        Debug.Log(message);
                    }
                }

                if (messageQueue.Count > 0)
                {
                    if (skin)
                    {
                        var color = skin.GetStyle("box").normal.textColor;
                        color.a = 0;
                        skin.GetStyle("box").normal.textColor = color;
                    }

                    isShowing = true;
                    isDisappearing = false;

                    var time = messageQueue.Peek().Value;
                    yield return new WaitForSeconds(time > 1 ? time - 0.5f : time / 2);
                    isDisappearing = true;
                    yield return new WaitForSeconds(time > 1 ? 0.5f : time / 2);

                    messageQueue.Dequeue();
                    isShowing = false;
                }
                else
                {
                    yield return 0;
                }
            }
        }

        private void OnGUI()
        {
            if (!isShowing || !skin)
            {
                return;
            }

            var color = skin.GetStyle("box").normal.textColor;
            color.a += isDisappearing ? -Time.deltaTime * 2 : Time.deltaTime * 2;
            color.a = color.a > 1 ? 1 : (color.a < 0 ? 0 : color.a);
            skin.GetStyle("box").normal.textColor = color;
            GUI.Box(new Rect(0, Screen.height / 2, Screen.width, Math.Min(Screen.height / 4, 160)), messageQueue.Peek().Key, skin.GetStyle("box"));
        }
    }

    /// <summary>
    /// <para xml:lang="en">Exception that need popup for notification.</para>
    /// <para xml:lang="zh">需要通过弹窗提示的异常。</para>
    /// </summary>
    public class UIPopupException : Exception
    {
        public UIPopupException(string message, float seconds) : base(message)
        {
            GUIPopup.EnqueueMessage(message, seconds);
        }

        public UIPopupException(string message) : this(message, 10)
        {
        }
    }
}