@@ -21,55 +21,51 @@ namespace MaterialDesignThemes.Wpf
21
21
{
22
22
[ TemplateVisualState ( GroupName = "CommonStates" , Name = TemplateStateNormal ) ]
23
23
[ TemplateVisualState ( GroupName = "CommonStates" , Name = TemplateStateMousePressed ) ]
24
+ [ TemplateVisualState ( GroupName = "CommonStates" , Name = TemplateStateMouseOut ) ]
24
25
public class Ripple : ContentControl
25
26
{
26
27
public const string TemplateStateNormal = "Normal" ;
27
28
public const string TemplateStateMousePressed = "MousePressed" ;
29
+ public const string TemplateStateMouseOut = "MouseOut" ;
28
30
29
- private static readonly HashSet < Ripple > LoadedInstances = new HashSet < Ripple > ( ) ;
31
+ private static readonly HashSet < Ripple > PressedInstances = new HashSet < Ripple > ( ) ;
30
32
31
33
static Ripple ( )
32
34
{
33
35
DefaultStyleKeyProperty . OverrideMetadata ( typeof ( Ripple ) , new FrameworkPropertyMetadata ( typeof ( Ripple ) ) ) ;
34
36
35
37
EventManager . RegisterClassHandler ( typeof ( Window ) , Mouse . PreviewMouseUpEvent , new MouseButtonEventHandler ( MouseButtonEventHandler ) , true ) ;
38
+ EventManager . RegisterClassHandler ( typeof ( Window ) , Mouse . MouseMoveEvent , new MouseEventHandler ( MouseMouveEventHandler ) , true ) ;
36
39
}
37
40
38
41
public Ripple ( )
39
42
{
40
- SizeChanged += OnSizeChanged ;
41
-
42
- Loaded += ( sender , args ) => LoadedInstances . Add ( ( Ripple ) sender ) ;
43
- Unloaded += ( sender , args ) => LoadedInstances . Remove ( ( Ripple ) sender ) ;
43
+ SizeChanged += OnSizeChanged ;
44
44
}
45
45
46
46
private static void MouseButtonEventHandler ( object sender , MouseButtonEventArgs e )
47
47
{
48
- foreach ( var loadedInstance in LoadedInstances )
49
- VisualStateManager . GoToState ( loadedInstance , TemplateStateNormal , false ) ;
48
+ foreach ( var ripple in PressedInstances )
49
+ VisualStateManager . GoToState ( ripple , TemplateStateNormal , false ) ;
50
+ PressedInstances . Clear ( ) ;
50
51
}
51
52
52
- private void OnSizeChanged ( object sender , SizeChangedEventArgs sizeChangedEventArgs )
53
+ private static void MouseMouveEventHandler ( object sender , MouseEventArgs e )
53
54
{
54
- var innerContent = ( Content as FrameworkElement ) ;
55
-
56
- double width , height ;
57
-
58
- if ( RippleAssist . GetIsCentered ( this ) && innerContent != null )
59
- {
60
- width = innerContent . ActualWidth ;
61
- height = innerContent . ActualHeight ;
62
- }
63
- else
55
+ foreach ( var ripple in PressedInstances . ToList ( ) )
64
56
{
65
- width = sizeChangedEventArgs . NewSize . Width ;
66
- height = sizeChangedEventArgs . NewSize . Height ;
67
- }
57
+ var relativePosition = Mouse . GetPosition ( ripple ) ;
58
+ if ( relativePosition . X < 0
59
+ || relativePosition . Y < 0
60
+ || relativePosition . X >= ripple . ActualWidth
61
+ || relativePosition . Y >= ripple . ActualHeight )
68
62
69
- var radius = Math . Sqrt ( Math . Pow ( width , 2 ) + Math . Pow ( height , 2 ) ) ;
70
-
71
- RippleSize = 2 * radius * RippleAssist . GetRippleSizeMultiplier ( this ) ;
72
- }
63
+ {
64
+ VisualStateManager . GoToState ( ripple , TemplateStateMouseOut , true ) ;
65
+ PressedInstances . Remove ( ripple ) ;
66
+ }
67
+ }
68
+ }
73
69
74
70
public static readonly DependencyProperty FeedbackProperty = DependencyProperty . Register (
75
71
"Feedback" , typeof ( Brush ) , typeof ( Ripple ) , new PropertyMetadata ( default ( Brush ) ) ) ;
@@ -108,7 +104,9 @@ protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
108
104
RippleY = point . Y - RippleSize / 2 ;
109
105
}
110
106
107
+ VisualStateManager . GoToState ( this , TemplateStateNormal , false ) ;
111
108
VisualStateManager . GoToState ( this , TemplateStateMousePressed , true ) ;
109
+ PressedInstances . Add ( this ) ;
112
110
113
111
base . OnPreviewMouseLeftButtonDown ( e ) ;
114
112
}
@@ -161,5 +159,27 @@ public override void OnApplyTemplate()
161
159
162
160
VisualStateManager . GoToState ( this , TemplateStateNormal , false ) ;
163
161
}
162
+
163
+ private void OnSizeChanged ( object sender , SizeChangedEventArgs sizeChangedEventArgs )
164
+ {
165
+ var innerContent = ( Content as FrameworkElement ) ;
166
+
167
+ double width , height ;
168
+
169
+ if ( RippleAssist . GetIsCentered ( this ) && innerContent != null )
170
+ {
171
+ width = innerContent . ActualWidth ;
172
+ height = innerContent . ActualHeight ;
173
+ }
174
+ else
175
+ {
176
+ width = sizeChangedEventArgs . NewSize . Width ;
177
+ height = sizeChangedEventArgs . NewSize . Height ;
178
+ }
179
+
180
+ var radius = Math . Sqrt ( Math . Pow ( width , 2 ) + Math . Pow ( height , 2 ) ) ;
181
+
182
+ RippleSize = 2 * radius * RippleAssist . GetRippleSizeMultiplier ( this ) ;
183
+ }
164
184
}
165
185
}
0 commit comments