[NUI] Introduce Notification (#1570)
authorJiyun Yang <ji.yang@samsung.com>
Wed, 29 Apr 2020 07:28:46 +0000 (16:28 +0900)
committerGitHub <noreply@github.com>
Wed, 29 Apr 2020 07:28:46 +0000 (16:28 +0900)
Signed-off-by: Jiyun Yang <ji.yang@samsung.com>
src/Tizen.NUI.Components/Controls/Notification.cs [new file with mode: 0644]

diff --git a/src/Tizen.NUI.Components/Controls/Notification.cs b/src/Tizen.NUI.Components/Controls/Notification.cs
new file mode 100644 (file)
index 0000000..946e088
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Copyright(c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// Notification helps to raise a notification window with a content View.
+    /// </summary>
+    /// <privilege>http://tizen.org/privilege/window.priority.set</privilege>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class Notification
+    {
+        private Window notificationWindow;
+
+        private Timer timer;
+
+        private NotificationLevel level = NotificationLevel.Base;
+
+        private Rectangle positionSize;
+
+        private bool dismissOnTouch = false;
+
+        private Animation onPostAnimation;
+
+        private Animation onDismissAnimation;
+
+        private NotificationState state = NotificationState.Ready;
+
+        /// <summary>
+        /// Create a notification with a content View.
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when a given contentView is invalid.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Notification(View contentView)
+        {
+            if (contentView == null)
+            {
+                throw (new ArgumentException("Input contentView should not be null."));
+            }
+
+            ContentView = contentView;
+        }
+
+        private enum NotificationState
+        {
+            Ready,
+            Post,
+            Dismiss,
+        }
+
+        /// <summary>
+        /// The content view received in a constructor.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View ContentView { get; private set; }
+
+        private Window NotificationWindow
+        {
+            get
+            {
+                if (notificationWindow == null)
+                {
+                    notificationWindow = new Window(null, true);
+                    notificationWindow.Type = WindowType.Notification;
+                    notificationWindow.Show();
+                }
+
+                return notificationWindow;
+            }
+            set => notificationWindow = value;
+        }
+
+        private Timer Timer
+        {
+            get
+            {
+                if (timer == null)
+                {
+                    timer = new Timer(0);
+                    timer.Tick += OnTimeOut;
+                }
+
+                return timer;
+            }
+            set
+            {
+                if (timer != null && timer.IsRunning())
+                {
+                    timer.Stop();
+                }
+
+                timer = value;
+            }
+        }
+
+        /// <summary>
+        /// Post a notification window with the content view.
+        /// </summary>
+        /// <param name="duration">Dismiss the notification window after given time. The value 0 won't dismiss the notification.</param>
+        /// <returns>The current Notification instance.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Post(uint duration = 0)
+        {
+            if (state != NotificationState.Ready)
+            {
+                return;
+            }
+
+            var window = NotificationWindow;
+
+            ApplyLevel(level);
+
+            ApplyPositionSize(positionSize);
+
+            ApplyDismissOnTouch(dismissOnTouch);
+
+            NotificationWindow.Add(ContentView);
+
+            if (duration > 0)
+            {
+                Timer.Interval = duration;
+            }
+
+            state = NotificationState.Post;
+
+            onPostAnimation.Play();
+        }
+
+        /// <summary>
+        /// Sets a priority level for the specified notification window.
+        /// </summary>
+        /// <param name="level">The notification window level.</param>
+        /// <returns>The current Notification instance.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Notification SetLevel(NotificationLevel level)
+        {
+            this.level = level;
+
+            if (state == NotificationState.Post)
+            {
+                ApplyLevel(level);
+            }
+
+            return this;
+        }
+
+        /// <summary>
+        /// Sets position and size of the notification window.
+        /// </summary>
+        /// <param name="positionSize">The position and size information in rectangle.</param>
+        /// <returns>The current Notification instance.</returns>
+        /// <exception cref="ArgumentException">Thrown when a given positionSize is invalid.</exception>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Notification SetPositionSize(Rectangle positionSize)
+        {
+            if (positionSize == null)
+            {
+                throw (new ArgumentException("Input positionSize should not be null."));
+            }
+
+            this.positionSize = positionSize;
+
+            if (state == NotificationState.Post || state == NotificationState.Dismiss)
+            {
+                ApplyPositionSize(positionSize);
+            }
+
+            return this;
+        }
+
+        /// <summary>
+        /// Sets whether listen to touch event to dismiss notification window.
+        /// </summary>
+        /// <param name="dismissOnTouch">Dismiss notification window on touch if the value is true.</param>
+        /// <returns>The current Notification instance.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Notification SetDismissOnTouch(bool dismissOnTouch)
+        {
+            if (this.dismissOnTouch == dismissOnTouch)
+            {
+                return this;
+            }
+
+            this.dismissOnTouch = dismissOnTouch;
+
+            if (state == NotificationState.Post)
+            {
+                ApplyDismissOnTouch(dismissOnTouch);
+            }
+
+            return this;
+        }
+
+        /// <summary>
+        /// Sets a user-defined animation to play when posting the notification.
+        /// The Notification will play the given animation right after the notification window pops up.
+        /// </summary>
+        /// <param name="animation">The animation to play.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Notification SetAnimationOnPost(Animation animation)
+        {
+            this.onPostAnimation = animation;
+
+            return this;
+        }
+
+        /// <summary>
+        /// Sets a user-defined animation to play when dismiss the notification.
+        /// On dismiss, the given animation is played, and after the playback is completed the notification window is undisplayed.
+        /// </summary>
+        /// <param name="animation">The animation to play.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Notification SetAnimationOnDismiss(Animation animation)
+        {
+            this.onDismissAnimation = animation;
+
+            return this;
+        }
+
+        /// <summary>
+        /// Dismiss the notification window.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Dismiss()
+        {
+            if (state != NotificationState.Post)
+            {
+                return;
+            }
+
+            state = NotificationState.Dismiss;
+
+            if (onDismissAnimation != null)
+            {
+                onDismissAnimation.Finished += OnAnimationEnd;
+
+                onDismissAnimation.Play();
+
+                Timer = null;
+
+                ApplyDismissOnTouch(false);
+
+                return;
+            }
+
+            ClearAll();
+        }
+
+        /// <summary>
+        /// Dismiss the notification window directly without calling OnDismissDelegate.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void ForceQuit()
+        {
+            if (state != NotificationState.Post && state != NotificationState.Dismiss)
+            {
+                return;
+            }
+
+            ClearAll();
+        }
+
+        private void DestroyNotificationWindow()
+        {
+            notificationWindow.Hide();
+
+            notificationWindow.Dispose();
+
+            notificationWindow = null;
+        }
+
+        private void ApplyLevel(NotificationLevel level)
+        {
+            NotificationWindow.SetNotificationLevel(level);
+        }
+
+        private void ApplyPositionSize(Rectangle positionSize)
+        {
+            if (positionSize != null)
+            {
+                NotificationWindow.SetPositionSize(positionSize);
+            }
+        }
+
+        private void ApplyDismissOnTouch(bool dismissOnTouch)
+        {
+            if (dismissOnTouch)
+            {
+                NotificationWindow.TouchEvent += OnWindowTouch;                    
+            }
+            else
+            {
+                NotificationWindow.TouchEvent -= OnWindowTouch;
+            }
+        }
+
+        private void ClearAll()
+        {
+            notificationWindow.Remove(ContentView);
+
+            Timer = null;
+
+            DestroyNotificationWindow();
+
+            state = NotificationState.Ready;
+        }
+
+        private void OnWindowTouch(object target, Window.TouchEventArgs args)
+        {
+            Dismiss();
+        }
+
+        private bool OnTimeOut(object target, Timer.TickEventArgs args)
+        {
+            Dismiss();
+
+            return false;
+        }
+
+        private void OnAnimationEnd(object target, EventArgs args)
+        {
+            onDismissAnimation.Finished -= OnAnimationEnd;
+
+            ClearAll();
+        }
+    }
+}
\ No newline at end of file