using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; namespace Muchinfo.DataPager.Base { public class MuchinfoPagerNavigationButton : Button { public static readonly DependencyProperty HoverDelayProperty; public static readonly DependencyProperty CornerRadiusProperty; [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public static readonly DependencyProperty InnerCornerRadiusProperty; public static readonly DependencyProperty IsBackgroundVisibleProperty; public static readonly RoutedEvent ActivateEvent; public static readonly RoutedEvent HoverEvent; private DispatcherTimer hoverTimer; public event EventHandler Activate { add { base.AddHandler(MuchinfoPagerNavigationButton.ActivateEvent, value); } remove { base.RemoveHandler(MuchinfoPagerNavigationButton.ActivateEvent, value); } } [Browsable(false)] public event EventHandler Hover { add { base.AddHandler(MuchinfoPagerNavigationButton.HoverEvent, value); } remove { base.RemoveHandler(MuchinfoPagerNavigationButton.HoverEvent, value); } } [Browsable(false)] public TimeSpan HoverDelay { get { return (TimeSpan)base.GetValue(MuchinfoPagerNavigationButton.HoverDelayProperty); } set { base.SetValue(MuchinfoPagerNavigationButton.HoverDelayProperty, value); } } public CornerRadius CornerRadius { get { return (CornerRadius)base.GetValue(MuchinfoPagerNavigationButton.CornerRadiusProperty); } set { base.SetValue(MuchinfoPagerNavigationButton.CornerRadiusProperty, value); } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public CornerRadius InnerCornerRadius { get { return (CornerRadius)base.GetValue(MuchinfoPagerNavigationButton.InnerCornerRadiusProperty); } set { base.SetValue(MuchinfoPagerNavigationButton.InnerCornerRadiusProperty, value); } } [Browsable(false)] public bool IsBackgroundVisible { get { return (bool)base.GetValue(MuchinfoPagerNavigationButton.IsBackgroundVisibleProperty); } set { base.SetValue(MuchinfoPagerNavigationButton.IsBackgroundVisibleProperty, value); } } static MuchinfoPagerNavigationButton() { MuchinfoPagerNavigationButton.HoverDelayProperty = DependencyProperty.Register("HoverDelay", typeof(TimeSpan), typeof(MuchinfoPagerNavigationButton), new PropertyMetadata(TimeSpan.Zero, new PropertyChangedCallback(MuchinfoPagerNavigationButton.OnHoverDelayChanged))); MuchinfoPagerNavigationButton.CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(MuchinfoPagerNavigationButton), new PropertyMetadata(new PropertyChangedCallback(MuchinfoPagerNavigationButton.OnCornerRadiusChanged))); MuchinfoPagerNavigationButton.InnerCornerRadiusProperty = DependencyProperty.Register("InnerCornerRadius", typeof(CornerRadius), typeof(MuchinfoPagerNavigationButton), new PropertyMetadata()); MuchinfoPagerNavigationButton.IsBackgroundVisibleProperty = DependencyProperty.Register("IsBackgroundVisible", typeof(bool), typeof(MuchinfoPagerNavigationButton), new PropertyMetadata(true, new PropertyChangedCallback(MuchinfoPagerNavigationButton.OnIsBackgroundVisiblePropertyChanged))); MuchinfoPagerNavigationButton.ActivateEvent = EventManager.RegisterRoutedEvent("Activate", RoutingStrategy.Bubble, typeof(EventHandler), typeof(MuchinfoPagerNavigationButton)); MuchinfoPagerNavigationButton.HoverEvent = EventManager.RegisterRoutedEvent("Hover", RoutingStrategy.Bubble, typeof(EventHandler), typeof(MuchinfoPagerNavigationButton)); FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(MuchinfoPagerNavigationButton), new FrameworkPropertyMetadata(typeof(MuchinfoPagerNavigationButton))); } public MuchinfoPagerNavigationButton() { //TelerikLicense.Verify(this); } public override void OnApplyTemplate() { base.OnApplyTemplate(); this.UpdateVisualStates(false); this.UpdateBackgroundVisibility(); } internal static MuchinfoRoutedEventArgs RaiseRadRoutedEvent(RoutedEvent routedEvent, UIElement source) { MuchinfoRoutedEventArgs radRoutedEventArgs = new MuchinfoRoutedEventArgs(routedEvent, source); source.RaiseEvent(radRoutedEventArgs); return radRoutedEventArgs; } internal static bool HasChildOf(DependencyObject parent, DependencyObject child, bool skipParent) { if (parent == null || child == null) { return false; } if (!skipParent && parent == child) { return true; } FrameworkElement frameworkElement = child as FrameworkElement; DependencyObject parent2 = VisualTreeHelper.GetParent(child); if (parent2 == null && frameworkElement != null) { parent2 = frameworkElement.Parent; } return MuchinfoPagerNavigationButton.HasChildOf(parent, parent2, false); } internal virtual void UpdateVisualStates(bool useTransitions) { if (!base.IsEnabled) { this.GoToState("Disabled", useTransitions); } else { if (base.IsPressed) { this.GoToState("Pressed", useTransitions); } else { if (base.IsMouseOver) { this.GoToState("MouseOver", useTransitions); } else { this.GoToState("Normal", useTransitions); } } } if (base.IsFocused && base.IsEnabled) { this.GoToState("Focused", useTransitions); return; } this.GoToState("Unfocused", useTransitions); } internal virtual void UpdateBackgroundVisibility() { if (this.IsBackgroundVisible || base.IsMouseOver || base.IsPressed) { this.GoToState("BackgroundVisible", false); } else { this.GoToState("BackgroundHidden", false); } if (this.IsBackgroundVisible) { this.GoToState("BackgroundIsVisible", false); return; } this.GoToState("BackgroundIsHidden", false); } internal bool GoToState(string stateName, bool useTransitions) { return VisualStateManager.GoToState(this, stateName, useTransitions); } internal void OnClickInternal() { this.OnClick(); } protected internal virtual void OnActivate() { base.RaiseEvent(new MuchinfoRoutedEventArgs(MuchinfoPagerNavigationButton.ActivateEvent, this)); } protected internal virtual void OnHover() { base.RaiseEvent(new MuchinfoRoutedEventArgs(MuchinfoPagerNavigationButton.HoverEvent, this)); } protected override void OnClick() { base.OnClick(); this.OnActivate(); //TraceMonitor.TrackAtomicFeature(this, "Click"); } protected override void OnLostFocus(RoutedEventArgs e) { base.OnLostFocus(e); this.UpdateBackgroundVisibility(); } protected override void OnGotFocus(RoutedEventArgs e) { base.OnGotFocus(e); this.UpdateBackgroundVisibility(); } protected override void OnMouseEnter(MouseEventArgs e) { base.OnMouseEnter(e); this.HoverTimerStart(); this.UpdateBackgroundVisibility(); } protected override void OnMouseLeave(MouseEventArgs e) { this.HoverTimerStop(); base.OnMouseLeave(e); this.UpdateBackgroundVisibility(); } protected override void OnMouseMove(MouseEventArgs e) { this.HoverTimerRestart(); base.OnMouseMove(e); } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); } private static void OnHoverDelayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MuchinfoPagerNavigationButton radButton = d as MuchinfoPagerNavigationButton; if (radButton != null) { radButton.HoverTimerApplyState(true); } } private static void OnCornerRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MuchinfoPagerNavigationButton radButton = d as MuchinfoPagerNavigationButton; CornerRadius cornerRadius = (CornerRadius)e.NewValue; if (radButton != null) { radButton.InnerCornerRadius = new CornerRadius(Math.Max(0.0, cornerRadius.TopLeft - 1.0), Math.Max(0.0, cornerRadius.TopRight - 1.0), Math.Max(0.0, cornerRadius.BottomRight - 1.0), Math.Max(0.0, cornerRadius.BottomLeft - 1.0)); } } private static void OnIsBackgroundVisiblePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MuchinfoPagerNavigationButton radButton = d as MuchinfoPagerNavigationButton; if (radButton != null) { radButton.UpdateBackgroundVisibility(); } } private void OnHoverTimerTick(object sender, EventArgs e) { this.HoverTimerStop(); this.OnHover(); } private void HoverTimerDestroy() { if (this.hoverTimer != null) { this.hoverTimer.Stop(); this.hoverTimer.Tick -= new EventHandler(this.OnHoverTimerTick); this.hoverTimer = null; } } private void HoverTimerStart() { if (this.HoverTimerApplyState(false)) { this.hoverTimer.Start(); } } private void HoverTimerStop() { if (this.HoverTimerApplyState(false)) { this.hoverTimer.Stop(); } } private void HoverTimerRestart() { if (this.HoverTimerApplyState(false)) { this.hoverTimer.Start(); } } private bool HoverTimerApplyState(bool applyAction) { double totalMilliseconds = this.HoverDelay.TotalMilliseconds; if (totalMilliseconds > 0.0) { if (this.hoverTimer == null) { this.hoverTimer = new DispatcherTimer(); this.hoverTimer.Tick += new EventHandler(this.OnHoverTimerTick); } if (totalMilliseconds != this.hoverTimer.Interval.TotalMilliseconds) { this.hoverTimer.Interval = this.HoverDelay; } if (applyAction) { if (base.IsMouseOver) { this.HoverTimerStart(); } else { this.HoverTimerStop(); } } } else { this.HoverTimerDestroy(); } return this.hoverTimer != null; } } }