/*
* Copyright(c) 2022 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
{
///
/// This class creates a border UI.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public class DefaultBorder : IBorderInterface
{
#region Constant Fields
private static readonly string ResourcePath = FrameworkInformation.ResourcePath;
private static readonly string MinimalizeIcon = ResourcePath + "minimalize.png";
private static readonly string MaximalizeIcon = ResourcePath + "maximalize.png";
private static readonly string CloseIcon = ResourcePath + "close.png";
private static readonly string LeftCornerIcon = ResourcePath + "leftCorner.png";
private static readonly string RightCornerIcon = ResourcePath + "rightCorner.png";
private static readonly string DarkMinimalizeIcon = ResourcePath + "dark_minimalize.png";
private static readonly string DarkPreviousIcon = ResourcePath + "dark_smallwindow.png";
private static readonly string DarkCloseIcon = ResourcePath + "dark_close.png";
private static readonly string DarkLeftCornerIcon = ResourcePath + "dark_leftCorner.png";
private static readonly string DarkRightCornerIcon = ResourcePath + "dark_rightCorner.png";
private const uint DefaultHeight = 50;
private const uint DefaultLineThickness = 5;
private const uint DefaultTouchThickness = 20;
private static readonly Color DefaultBackgroundColor = new Color(1, 1, 1, 0.3f);
private static readonly Color DefaultClickedBackgroundColor = new Color(1, 1, 1, 0.4f);
private static readonly Size2D DefaultMinSize = new Size2D(100, 0);
#endregion //Constant Fields
#region Fields
private Color backgroundColor;
private View borderView;
private ImageView minimalizeIcon;
private ImageView maximalizeIcon;
private ImageView closeIcon;
private ImageView leftCornerIcon;
private ImageView rightCornerIcon;
private Window.BorderDirection direction = Window.BorderDirection.None;
private float preScale = 0;
private View windowView = null;
private bool isWinGestures = false;
private Timer timer;
private Timer overlayTimer;
private CurrentGesture currentGesture = CurrentGesture.None;
private bool disposed = false;
#endregion //Fields
#region Events
private PanGestureDetector borderPanGestureDetector;
private PinchGestureDetector borderPinchGestureDetector;
private PanGestureDetector winPanGestureDetector;
private TapGestureDetector winTapGestureDetector;
#endregion //Events
#region Enums
private enum CurrentGesture
{
None = 0,
TapGesture = 1,
PanGesture = 2,
PinchGesture = 3,
}
#endregion //Enums
#region Methods
///
/// The thickness of the border.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public uint BorderLineThickness {get; set;}
///
/// The thickness of the border's touch area.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public uint TouchThickness {get; set;}
///
/// The height of the border.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public uint BorderHeight {get; set;}
///
/// The minimum size by which the window will small.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public Size2D MinSize {get; set;}
///
/// The maximum size by which the window will big.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public Size2D MaxSize {get; set;}
///
/// The window with borders added.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public Window BorderWindow {get; set;}
///
/// Whether overlay mode.
/// If overlay mode is true, the border area is hidden when the window is maximized.
/// And if you touched at screen, the border area is shown on the screen.
/// Default value is false;
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool OverlayMode {get; set;}
///
/// Set the window resizing policy.
/// Default value is BorderResizePolicyType.Free;
///
[EditorBrowsable(EditorBrowsableState.Never)]
public Window.BorderResizePolicyType ResizePolicy {get; set;}
///
/// Creates a default border
///
[EditorBrowsable(EditorBrowsableState.Never)]
public DefaultBorder()
{
BorderLineThickness = DefaultLineThickness;
TouchThickness = DefaultTouchThickness;
BorderHeight = DefaultHeight;
MinSize = DefaultMinSize;
OverlayMode = false;
ResizePolicy = Window.BorderResizePolicyType.Free;
}
///
/// Create top border UI. User can override this method to draw top border UI.
///
/// The top view on which the border.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool CreateTopBorderView(View topView)
{
return false;
}
///
/// Create bottom border UI. User can override this method to draw bottom border UI.
///
/// The bottom view on which the border.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool CreateBottomBorderView(View bottomView)
{
if (bottomView == null)
{
return false;
}
bottomView.Layout = new RelativeLayout();
minimalizeIcon = new ImageView()
{
Focusable = true,
ResourceUrl = MinimalizeIcon,
AccessibilityHighlightable = true,
};
maximalizeIcon = new ImageView()
{
Focusable = true,
ResourceUrl = MaximalizeIcon,
AccessibilityHighlightable = true,
};
closeIcon = new ImageView()
{
Focusable = true,
ResourceUrl = CloseIcon,
AccessibilityHighlightable = true,
};
leftCornerIcon = new ImageView()
{
Focusable = true,
ResourceUrl = LeftCornerIcon,
AccessibilityHighlightable = true,
};
rightCornerIcon = new ImageView()
{
Focusable = true,
ResourceUrl = RightCornerIcon,
AccessibilityHighlightable = true,
};
RelativeLayout.SetRightTarget(minimalizeIcon, maximalizeIcon);
RelativeLayout.SetRightRelativeOffset(minimalizeIcon, 0.0f);
RelativeLayout.SetHorizontalAlignment(minimalizeIcon, RelativeLayout.Alignment.End);
RelativeLayout.SetRightTarget(maximalizeIcon, closeIcon);
RelativeLayout.SetRightRelativeOffset(maximalizeIcon, 0.0f);
RelativeLayout.SetHorizontalAlignment(maximalizeIcon, RelativeLayout.Alignment.End);
RelativeLayout.SetRightTarget(closeIcon, rightCornerIcon);
RelativeLayout.SetRightRelativeOffset(closeIcon, 0.0f);
RelativeLayout.SetHorizontalAlignment(closeIcon, RelativeLayout.Alignment.End);
RelativeLayout.SetRightRelativeOffset(rightCornerIcon, 1.0f);
RelativeLayout.SetHorizontalAlignment(rightCornerIcon, RelativeLayout.Alignment.End);
bottomView.Add(leftCornerIcon);
bottomView.Add(minimalizeIcon);
bottomView.Add(maximalizeIcon);
bottomView.Add(closeIcon);
bottomView.Add(rightCornerIcon);
minimalizeIcon.TouchEvent += OnMinimizeIconTouched;
maximalizeIcon.TouchEvent += OnMaximizeIconTouched;
closeIcon.TouchEvent += OnCloseIconTouched;
leftCornerIcon.TouchEvent += OnLeftBottomCornerIconTouched;
rightCornerIcon.TouchEvent += OnRightBottomCornerIconTouched;
minimalizeIcon.AccessibilityActivated += (s, e) =>
{
MinimizeBorderWindow();
};
maximalizeIcon.AccessibilityActivated += (s, e) =>
{
MaximizeBorderWindow();
};
closeIcon.AccessibilityActivated += (s, e) =>
{
CloseBorderWindow();
};
minimalizeIcon.AccessibilityNameRequested += (s, e) =>
{
e.Name = "Minimize";
};
maximalizeIcon.AccessibilityNameRequested += (s, e) =>
{
e.Name = "Maximize";
};
closeIcon.AccessibilityNameRequested += (s, e) =>
{
e.Name = "Close";
};
leftCornerIcon.AccessibilityNameRequested += (s, e) =>
{
e.Name = "Resize";
};
rightCornerIcon.AccessibilityNameRequested += (s, e) =>
{
e.Name = "Resize";
};
minimalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
maximalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
closeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
leftCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
rightCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
return true;
}
///
/// Create border UI. User can override this method to draw border UI.
/// A top border and a bottom border are added to this view.
///
/// The root view on which the border.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void CreateBorderView(View borderView)
{
if (borderView == null)
{
return;
}
this.borderView = borderView;
borderView.BackgroundColor = DefaultBackgroundColor;
borderView.CornerRadius = new Vector4(0.03f, 0.03f, 0.03f, 0.03f);
borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative;
}
/// Determines the behavior of pinch gesture.
private void OnPinchGestureDetected(object source, PinchGestureDetector.DetectedEventArgs e)
{
if (e == null)
{
return;
}
if (e.PinchGesture.State == Gesture.StateType.Started)
{
preScale = e.PinchGesture.Scale;
}
else if (e.PinchGesture.State == Gesture.StateType.Finished || e.PinchGesture.State == Gesture.StateType.Cancelled)
{
if (preScale > e.PinchGesture.Scale)
{
if (BorderWindow.IsMaximized())
{
BorderWindow.Maximize(false);
OnMaximize(false);
}
else
{
BorderWindow.Minimize(true);
OnMinimize(true);
}
}
else
{
BorderWindow.Maximize(true);
OnMaximize(true);
}
}
}
/// Determines the behavior of borders.
private void OnPanGestureDetected(object source, PanGestureDetector.DetectedEventArgs e)
{
if (e == null)
{
return;
}
PanGesture panGesture = e.PanGesture;
if (panGesture.State == Gesture.StateType.Started && panGesture.Position != null)
{
direction = BorderWindow.GetDirection(panGesture.Position.X, panGesture.Position.Y);
if (direction == Window.BorderDirection.Move)
{
if (BorderWindow.IsMaximized() == true)
{
BorderWindow.Maximize(false);
OnMaximize(false);
}
else
{
BorderWindow.RequestMoveToServer();
}
}
else if (direction != Window.BorderDirection.None && ResizePolicy != Window.BorderResizePolicyType.Fixed)
{
OnRequestResize();
BorderWindow.RequestResizeToServer((Window.ResizeDirection)direction);
}
}
else if (panGesture.State == Gesture.StateType.Finished || panGesture.State == Gesture.StateType.Cancelled)
{
direction = Window.BorderDirection.None;
ClearWindowGesture();
}
}
///
/// This is an event callback when the left top corner icon is touched.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OnLeftTopCornerIconTouched(object sender, View.TouchEventArgs e)
{
if (e != null && e.Touch.GetState(0) == PointStateType.Down)
{
ClearWindowGesture();
if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
{
OnRequestResize();
BorderWindow.RequestResizeToServer(Window.ResizeDirection.TopLeft);
}
}
return true;
}
///
///This is an event callback when the right bottom corner icon is touched.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OnRightTopCornerIconTouched(object sender, View.TouchEventArgs e)
{
if (e != null && e.Touch.GetState(0) == PointStateType.Down)
{
ClearWindowGesture();
if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
{
OnRequestResize();
BorderWindow.RequestResizeToServer(Window.ResizeDirection.TopRight);
}
}
return true;
}
///
/// This is an event callback when the left bottom corner icon is touched.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OnLeftBottomCornerIconTouched(object sender, View.TouchEventArgs e)
{
if (e != null && e.Touch.GetState(0) == PointStateType.Down)
{
ClearWindowGesture();
if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
{
OnRequestResize();
BorderWindow.RequestResizeToServer(Window.ResizeDirection.BottomLeft);
}
}
return true;
}
///
///This is an event callback when the right bottom corner icon is touched.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OnRightBottomCornerIconTouched(object sender, View.TouchEventArgs e)
{
if (e != null && e.Touch.GetState(0) == PointStateType.Down)
{
ClearWindowGesture();
if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
{
OnRequestResize();
BorderWindow.RequestResizeToServer(Window.ResizeDirection.BottomRight);
}
}
return true;
}
///
/// Minimize border window.
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected void MinimizeBorderWindow()
{
ClearWindowGesture();
BorderWindow.Minimize(true);
OnMinimize(true);
}
///
/// This is an event callback when the minimize icon is touched.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OnMinimizeIconTouched(object sender, View.TouchEventArgs e)
{
if (e != null && e.Touch.GetState(0) == PointStateType.Up)
{
MinimizeBorderWindow();
}
return true;
}
///
/// Maximize border window.
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected void MaximizeBorderWindow()
{
ClearWindowGesture();
if (BorderWindow.IsMaximized())
{
BorderWindow.Maximize(false);
OnMaximize(false);
}
else
{
BorderWindow.Maximize(true);
OnMaximize(true);
}
}
///
/// This is an event callback when the maximum icon is touched.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OnMaximizeIconTouched(object sender, View.TouchEventArgs e)
{
if (e != null && e.Touch.GetState(0) == PointStateType.Up)
{
MaximizeBorderWindow();
}
return true;
}
///
/// Close border window.
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected void CloseBorderWindow()
{
BorderWindow.BorderDestroy();
}
///
/// This is an event callback when the close icon is touched.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OnCloseIconTouched(object sender, View.TouchEventArgs e)
{
if (e != null && e.Touch.GetState(0) == PointStateType.Up)
{
CloseBorderWindow();
}
return true;
}
private void UpdateIcons()
{
if (BorderWindow != null && borderView != null)
{
if (BorderWindow.IsMaximized() == true)
{
if (maximalizeIcon != null)
{
maximalizeIcon.ResourceUrl = DarkPreviousIcon;
}
if (minimalizeIcon != null)
{
minimalizeIcon.ResourceUrl = DarkMinimalizeIcon;
}
if (closeIcon != null)
{
closeIcon.ResourceUrl = DarkCloseIcon;
}
if (leftCornerIcon != null)
{
leftCornerIcon.ResourceUrl = DarkLeftCornerIcon;
}
if (rightCornerIcon != null)
{
rightCornerIcon.ResourceUrl = DarkRightCornerIcon;
}
borderView.CornerRadius = new Vector4(0, 0, 0, 0);
borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative;
BorderWindow.SetTransparency(false);
}
else
{
if (maximalizeIcon != null)
{
maximalizeIcon.ResourceUrl = MaximalizeIcon;
}
if (minimalizeIcon != null)
{
minimalizeIcon.ResourceUrl = MinimalizeIcon;
}
if (closeIcon != null)
{
closeIcon.ResourceUrl = CloseIcon;
}
if (leftCornerIcon != null)
{
leftCornerIcon.ResourceUrl = LeftCornerIcon;
}
if (rightCornerIcon != null)
{
rightCornerIcon.ResourceUrl = RightCornerIcon;
}
borderView.CornerRadius = new Vector4(0.03f, 0.03f, 0.03f, 0.03f);
borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative;
BorderWindow.SetTransparency(true);
}
}
}
///
/// Called after the border UI is created.
///
/// The border view on which the border.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void OnCreated(View borderView)
{
if (borderView == null)
{
return;
}
this.borderView = borderView;
// Register to resize and move through pan gestures.
borderPanGestureDetector = new PanGestureDetector();
borderPanGestureDetector.Attach(borderView);
borderPanGestureDetector.Detected += OnPanGestureDetected;
// Register touch event for effect when border is touched.
borderView.LeaveRequired = true;
borderView.TouchEvent += (s, e) =>
{
if (e.Touch.GetState(0) == PointStateType.Started)
{
if (BorderWindow.IsMaximized() == false)
{
BorderWindow.Raise();
}
backgroundColor = new Color(borderView.BackgroundColor);
borderView.BackgroundColor = DefaultClickedBackgroundColor;
}
else if (e.Touch.GetState(0) == PointStateType.Finished ||
e.Touch.GetState(0) == PointStateType.Leave ||
e.Touch.GetState(0) == PointStateType.Interrupted)
{
borderView.BackgroundColor = backgroundColor;
}
return true;
};
borderPinchGestureDetector = new PinchGestureDetector();
borderPinchGestureDetector.Attach(borderView);
borderPinchGestureDetector.Detected += OnPinchGestureDetected;
AddInterceptGesture();
UpdateIcons();
}
// Register an intercept touch event on the window.
private void AddInterceptGesture()
{
isWinGestures = false;
BorderWindow.InterceptTouchEvent += OnWinInterceptedTouch;
}
// Intercept touch on window.
private bool OnWinInterceptedTouch(object sender, Window.TouchEventArgs e)
{
if (e.Touch.GetState(0) == PointStateType.Stationary && e.Touch.GetPointCount() == 2)
{
if (isWinGestures == false && timer == null)
{
timer = new Timer(300);
timer.Tick += OnTick;
timer.Start();
}
}
else
{
currentGesture = CurrentGesture.None;
if (timer != null)
{
timer.Stop();
timer.Dispose();
timer = null;
}
}
return false;
}
// If two finger long press is done, create a windowView.
// then, Register a gesture on the windowView to do a resize or move.
private bool OnTick(object o, Timer.TickEventArgs e)
{
windowView = new View()
{
WidthResizePolicy = ResizePolicyType.FillToParent,
HeightResizePolicy = ResizePolicyType.FillToParent,
BackgroundColor = new Color(1, 1, 1, 0.5f),
};
windowView.TouchEvent += (s, e) =>
{
return true;
};
BorderWindow.Add(windowView);
winTapGestureDetector = new TapGestureDetector();
winTapGestureDetector.Attach(windowView);
winTapGestureDetector.SetMaximumTapsRequired(3);
winTapGestureDetector.Detected += OnWinTapGestureDetected;
winPanGestureDetector = new PanGestureDetector();
winPanGestureDetector.Attach(windowView);
winPanGestureDetector.Detected += OnWinPanGestureDetected;
BorderWindow.InterceptTouchEvent -= OnWinInterceptedTouch;
isWinGestures = true;
return false;
}
// Behavior when the window is tapped.
private void OnWinTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e)
{
if (currentGesture <= CurrentGesture.TapGesture)
{
currentGesture = CurrentGesture.TapGesture;
if (e.TapGesture.NumberOfTaps == 2)
{
if (BorderWindow.IsMaximized() == false)
{
BorderWindow.Maximize(true);
OnMaximize(true);
}
else
{
BorderWindow.Maximize(false);
OnMaximize(false);
}
}
else
{
ClearWindowGesture();
}
}
}
// Window moves through pan gestures.
private void OnWinPanGestureDetected(object source, PanGestureDetector.DetectedEventArgs e)
{
if (currentGesture <= CurrentGesture.PanGesture /*&& panGesture.NumberOfTouches == 1*/)
{
PanGesture panGesture = e.PanGesture;
if (panGesture.State == Gesture.StateType.Started)
{
currentGesture = CurrentGesture.PanGesture;
if (BorderWindow.IsMaximized() == true)
{
BorderWindow.Maximize(false);
OnMaximize(false);
}
else
{
BorderWindow.RequestMoveToServer();
}
}
else if (panGesture.State == Gesture.StateType.Finished || panGesture.State == Gesture.StateType.Cancelled)
{
currentGesture = CurrentGesture.None;
ClearWindowGesture();
}
}
}
private void ClearWindowGesture()
{
if (isWinGestures)
{
winPanGestureDetector.Dispose();
winTapGestureDetector.Dispose();
isWinGestures = false;
BorderWindow.Remove(windowView);
BorderWindow.InterceptTouchEvent += OnWinInterceptedTouch;
}
}
///
/// Called when requesting a resize
///
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void OnRequestResize() {}
///
/// Called when the window is resized.
///
/// The width of the resized window
/// The height of the resized window
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void OnResized(int width, int height)
{
if (overlayTimer != null)
{
overlayTimer.Stop();
overlayTimer.Dispose();
overlayTimer = null;
BorderWindow?.GetBorderWindowBottomLayer().LowerToBottom();
borderView?.Show();
}
UpdateIcons();
}
///
/// Called when the window is maximized.
///
/// If window is maximized or unmaximized.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void OnMaximize(bool isMaximized)
{
UpdateIcons();
}
///
/// Called when the window is minimized.
///
/// If window is mnimized or unminimized.
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual void OnMinimize(bool isMinimized)
{
UpdateIcons();
}
///
/// Show the border when OverlayMode is true and the window is now Maximize.
///
/// Time(ms) for borders to disappear again
/// True if border became show, false otherwise
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OverlayBorderShow(uint time = 3000)
{
if (BorderWindow != null && BorderWindow.IsMaximized())
{
if (overlayTimer == null)
{
overlayTimer = new Timer(time);
overlayTimer.Tick += (s, e) =>
{
BorderWindow.GetBorderWindowBottomLayer().LowerToBottom();
borderView?.Hide();
overlayTimer?.Stop();
overlayTimer?.Dispose();
overlayTimer = null;
return false;
};
overlayTimer.Start();
BorderWindow.GetBorderWindowBottomLayer().RaiseToTop();
borderView?.Show();
}
else
{
overlayTimer.Start();
}
return true;
}
return false;
}
///
/// Hide the border when OverlayMode is true and the window is now Maximize.
///
/// True if border became hide, false otherwise
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool OverlayBorderHide()
{
if (BorderWindow != null && BorderWindow.IsMaximized())
{
borderView?.Hide();
return true;
}
return false;
}
[EditorBrowsable(EditorBrowsableState.Never)]
protected virtual void Dispose(bool disposing)
{
if (disposed)
{
return;
}
if (disposing)
{
ClearWindowGesture();
if (BorderWindow != null)
{
BorderWindow.InterceptTouchEvent -= OnWinInterceptedTouch;
}
borderView?.Dispose();
windowView?.Dispose();
borderPanGestureDetector?.Dispose();
borderPinchGestureDetector?.Dispose();
backgroundColor?.Dispose();
minimalizeIcon?.Dispose();
maximalizeIcon?.Dispose();
closeIcon?.Dispose();
leftCornerIcon?.Dispose();
rightCornerIcon?.Dispose();
timer?.Dispose();
overlayTimer?.Dispose();
}
disposed = true;
}
///
/// Dispose
///
[EditorBrowsable(EditorBrowsableState.Never)]
public void Dispose()
{
Dispose(true);
global::System.GC.SuppressFinalize(this);
}
#endregion //Methods
}
}