From: Jiyun Yang Date: Wed, 29 Apr 2020 07:28:46 +0000 (+0900) Subject: [NUI] Introduce Notification (#1570) X-Git-Tag: accepted/tizen/unified/20210219.040944~755 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5452a850e2a5257a8290fc36b3f2a865a04d6777;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [NUI] Introduce Notification (#1570) Signed-off-by: Jiyun Yang --- diff --git a/src/Tizen.NUI.Components/Controls/Notification.cs b/src/Tizen.NUI.Components/Controls/Notification.cs new file mode 100644 index 0000000..946e088 --- /dev/null +++ b/src/Tizen.NUI.Components/Controls/Notification.cs @@ -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 +{ + /// + /// Notification helps to raise a notification window with a content View. + /// + /// http://tizen.org/privilege/window.priority.set + [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; + + /// + /// Create a notification with a content View. + /// + /// Thrown when a given contentView is invalid. + [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, + } + + /// + /// The content view received in a constructor. + /// + [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; + } + } + + /// + /// Post a notification window with the content view. + /// + /// Dismiss the notification window after given time. The value 0 won't dismiss the notification. + /// The current Notification instance. + [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(); + } + + /// + /// Sets a priority level for the specified notification window. + /// + /// The notification window level. + /// The current Notification instance. + [EditorBrowsable(EditorBrowsableState.Never)] + public Notification SetLevel(NotificationLevel level) + { + this.level = level; + + if (state == NotificationState.Post) + { + ApplyLevel(level); + } + + return this; + } + + /// + /// Sets position and size of the notification window. + /// + /// The position and size information in rectangle. + /// The current Notification instance. + /// Thrown when a given positionSize is invalid. + [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; + } + + /// + /// Sets whether listen to touch event to dismiss notification window. + /// + /// Dismiss notification window on touch if the value is true. + /// The current Notification instance. + [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; + } + + /// + /// 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. + /// + /// The animation to play. + [EditorBrowsable(EditorBrowsableState.Never)] + public Notification SetAnimationOnPost(Animation animation) + { + this.onPostAnimation = animation; + + return this; + } + + /// + /// 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. + /// + /// The animation to play. + [EditorBrowsable(EditorBrowsableState.Never)] + public Notification SetAnimationOnDismiss(Animation animation) + { + this.onDismissAnimation = animation; + + return this; + } + + /// + /// Dismiss the notification window. + /// + [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(); + } + + /// + /// Dismiss the notification window directly without calling OnDismissDelegate. + /// + [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