<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SHAZAML! &#187; MouseCursorBehavior</title>
	<atom:link href="http://www.shazaml.com/archives/tag/mousecursorbehavior/feed" rel="self" type="application/rss+xml" />
	<link>http://www.shazaml.com</link>
	<description>The Blog for Design &#38; Development Superheroes</description>
	<lastBuildDate>Wed, 28 Jul 2010 21:02:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Video: Creating a Silverlight 3 Casual Game using Blend 3 and Triggers, Actions, and Behaviors</title>
		<link>http://www.shazaml.com/archives/video-silverlight-casual-game</link>
		<comments>http://www.shazaml.com/archives/video-silverlight-casual-game#comments</comments>
		<pubDate>Mon, 09 Nov 2009 15:19:11 +0000</pubDate>
		<dc:creator>Mark Tucker</dc:creator>
				<category><![CDATA[Hidden Object Game]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Action]]></category>
		<category><![CDATA[Behavior]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[ChangePropertyAction]]></category>
		<category><![CDATA[ContinuousPlayMediaBehavior]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[GlobalCounterMinReachedTrigger]]></category>
		<category><![CDATA[GoToStateAction]]></category>
		<category><![CDATA[IncrementGlobalCounterAction]]></category>
		<category><![CDATA[InvokeCommandAction]]></category>
		<category><![CDATA[MagnifierOverBehavior]]></category>
		<category><![CDATA[MouseCursorBehavior]]></category>
		<category><![CDATA[ParticlesBehavior]]></category>
		<category><![CDATA[PlaySoundAction]]></category>
		<category><![CDATA[RemoveElementAction]]></category>
		<category><![CDATA[SetGlobalCounterAction]]></category>
		<category><![CDATA[SetInteractionPropertyAction]]></category>
		<category><![CDATA[ShowGlobalCounterBehavior]]></category>
		<category><![CDATA[Trigger]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[Visual State Manager]]></category>
		<category><![CDATA[VSM]]></category>

		<guid isPermaLink="false">http://www.shazaml.com/?p=333</guid>
		<description><![CDATA[Video presentation from Desert Code Camp 2009 - Silverlight 3 Casual Game]]></description>
			<content:encoded><![CDATA[<p>On Saturday, November 7, 2009 at 9:00am I presented at the Desert Code Camp in Phoenix, AZ. The topic of my presentation was Silverlight casual game development. In less than an hour I demonstrated how to use triggers, actions, and behaviors in Blend 3 to create a hidden object game. Because all code was contained in the TABs (Triggers, Actions, and Behaviors) there was no code behind for the main UserControl.</p>
<p>Here is a link to the <a title="Video - Creating a Silverlight 3 Casual Game using Blend 3 and Triggers, Actions, and Behaviors" href="http://www.shazaml.com/downloads/DesertCodeCamp2009-Silverlight3CasualGame.wmv">presentation video</a> in WMV format.</p>
<p>If you like you can see <a href="http://www.shazaml.com/archives/creating-a-hidden-object-game-in-silverlight-3">all the episodes</a> and follow along with the tutorial.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shazaml.com/archives/video-silverlight-casual-game/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
<enclosure url="http://www.shazaml.com/downloads/DesertCodeCamp2009-Silverlight3CasualGame.wmv" length="63294285" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Hidden Object: Episode 12 – Custom Mouse Cursor Behavior</title>
		<link>http://www.shazaml.com/archives/hidden-object-episode-12</link>
		<comments>http://www.shazaml.com/archives/hidden-object-episode-12#comments</comments>
		<pubDate>Tue, 27 Oct 2009 14:07:09 +0000</pubDate>
		<dc:creator>Mark Tucker</dc:creator>
				<category><![CDATA[Hidden Object Game]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Behavior]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[MouseCursorBehavior]]></category>

		<guid isPermaLink="false">http://www.shazaml.com/?p=309</guid>
		<description><![CDATA[With the MouseCursorBehavior it is easy to set custom mouse cursors.]]></description>
			<content:encoded><![CDATA[<p>This is episode 12 of <a href="http://www.shazaml.com/archives/creating-a-hidden-object-game-in-silverlight-3">Creating a Hidden Object Game is Silverlight 3</a>. In this episode, we will create a behavior that allows us to set the shape of the mouse cursor to any Image or Path we desire.</p>
<p>Let start this tutorial in <a href="http://www.microsoft.com/expression/products/Design_Overview.aspx">Expression Design</a>. Create a new document that is 25&#215;25 pixels and on the single layer add the shapes shown:</p>
<p> </p>
<p><a href="http://www.shazaml.com/wp-content/uploads/2009/10/102709_1407_HiddenObjec1.png"><img class="alignnone size-medium wp-image-303" title="102709_1407_HiddenObjec1.png" src="http://www.shazaml.com/wp-content/uploads/2009/10/102709_1407_HiddenObjec1-300x201.png" alt="102709_1407_HiddenObjec1.png" width="300" height="201" /></a> </p>
<p>Export the document as a PNG making sure that both Transparency and Antialias are checked.</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/102709_1407_HiddenObjec2.png" alt="" /></p>
<p> </p>
<p>If you don&#8217;t have a copy of Expression Design, you can use a vector graphics program like <a href="http://www.inkscape.org/">Inkscape</a>.</p>
<p> </p>
<p>Add the image to the Visual Studio project and drag it onto the Canvas. Let&#8217;s position the cursor image off screen at: Top = -50 and Left = -5. The -5 positions the cursor so the tip of the arrow is right in the corner and the -50 just to get it off screen. Since this image needs to be over all other objects including the screen Canvas objects, let&#8217;s set the ZIndex property to 1000.</p>
<p>We will compensate for the Top value with the OffsetY value in the MouseCursorBehavior that we will create:</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/102709_1407_HiddenObjec3.png" alt="" /></p>
<p> </p>
<p>The two offset values are dependency properties of type Double whereas CursorName is a string. You will notice that the cursor name has the artboard element picker (target symbol) that allows you to pick an object from the artboard.</p>
<p>Under the Interactivity folder, create a folder called MouseCursor and add three class files: MouseCursorBehavior, NameResolvedEventArgs, and NameResolver.</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/102709_1407_HiddenObjec4.png" alt="" /></p>
<p>To get NameResolver and NameResolvedEventArgs, I admit that I used <a href="http://www.red-gate.com/products/reflector/">.NET Reflector</a> to understand how the TargetedTriggerAction class was able to get a reference to an instance of the Target class using the string dependency property, TargetName.</p>
<p>Here is a sample usage of the NameResolver class as it relates to the MouseCursorBehavior:</p>
<pre class="brush: csharp; gutter: false;">
NameResolver cursorResolver = new NameResolver();
cursorResolver.NameScopeReferenceElement = AssociatedObject;
cursorResolver.Name = &quot;cursorArrow&quot;;
DependencyObject cursor = cursorResolver.Object;
 </pre>
<p>After creating an instance of the NameResolver, we must assign an object as the NameScopeReferenceElement and set the name of the element that will be our cursor. Calling the Object property on the resolver will return a reference to the object specified by the Name property. The key method in NameResolver is UpdateObjectFromName:</p>
<pre class="brush: csharp; gutter: true;">
private void UpdateObjectFromName(DependencyObject oldObject)
{
    DependencyObject resolvedObject = null;
    this.ResolvedObject = null;
 
    if (this.NameScopeReferenceElement != null)
    {
        if (!IsElementLoaded(this.NameScopeReferenceElement))
        {
            this.NameScopeReferenceElement.Loaded += new RoutedEventHandler(this.OnNameScopeReferenceLoaded);
            this.PendingReferenceElementLoad = true;
            return;
        }
        if (!string.IsNullOrEmpty(this.Name))
        {
            FrameworkElement actualNameScopeReferenceElement = this.ActualNameScopeReferenceElement;
            if (actualNameScopeReferenceElement != null)
            {
                resolvedObject = actualNameScopeReferenceElement.FindName(this.Name) as DependencyObject;
            }
        }
    }
    this.HasAttempedResolve = true;
    this.ResolvedObject = resolvedObject;
    if (oldObject != this.Object)
    {
        this.OnObjectChanged(oldObject, this.Object);
    }
}
</pre>
<p> </p>
<p>Line 19 shows how NameScopeReferenceElement and Name are used to resolve the actual object.</p>
<p>The MouseCursorBehavior class defines three dependency properties with their corresponding .NET properties:</p>
<pre class="brush: csharp; gutter: false;">
public static readonly DependencyProperty CursorNameProperty =
     DependencyProperty.Register(&quot;CursorName&quot;, typeof(string), typeof(MouseCursorBehavior),
     new PropertyMetadata(new PropertyChangedCallback(OnCursorNameChanged)));
 
public static readonly DependencyProperty OffsetXProperty =
    DependencyProperty.Register(&quot;OffsetX&quot;, typeof(double), typeof(MouseCursorBehavior), null);
    
public static readonly DependencyProperty OffsetYProperty =
    DependencyProperty.Register(&quot;OffsetY&quot;, typeof(double), typeof(MouseCursorBehavior), null);
 </pre>
<p>In the constructor of the behavior, a NameResolver called cursorResolver is created. In the OnAttached method, the resolver&#8217;s NameScopeReferenceElement is set to the AssociatedObject. And in the OnCursorChanged method, the Name property is set to the name of the object to be used as the cursor:</p>
<pre class="brush: csharp; gutter: false;">
private static void OnCursorNameChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    MouseCursorBehavior behavior = (MouseCursorBehavior)obj;
    behavior.CursorResolver.Name = (string)args.NewValue;
}
</pre>
<p>To get the artboard element picker to show in the Properties panel for the CursorName, add the CustomPropertyValueEditor attribute to the CursorName property and specify the editor for an Element:</p>
<pre class="brush: csharp; gutter: false;">
[CustomPropertyValueEditor(CustomPropertyValueEditor.Element)]
public string CursorName
{
    get
    {
        return (string)base.GetValue(CursorNameProperty);
    }
    set
    {
        base.SetValue(CursorNameProperty, value);
    }
}
 </pre>
<p>The Cursor property is where the CursorName value is resolved by the NameResolver and the object reference is returned.</p>
<p>Now the behavior has a reference to the image that is being used as a cursor, now it needs to use that instead of the default cursor. In the OnAttached method, the behavior registers to handle the MouseEnter and MouseLeave events of the AssociatedObject. In our case, the MouseCursorBehavior will be attached to the MainPage UserControl which becomes the AssociatedObject. So whenever the mouse enters the area of the UserControl, it will be changed to the arrow:</p>
<pre class="brush: csharp; gutter: false;">
private void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)
{
    if (!this.IsCursorNameSet)
        return;
 
    FrameworkElement cursor = Cursor as FrameworkElement;
 
    cursor.Visibility = Visibility.Visible;
    AssociatedObject.Cursor = Cursors.None;
    cursor.IsHitTestVisible = false;
 
    this.AssociatedObject.MouseMove += new MouseEventHandler(AssociatedObject_MouseMove);
}
</pre>
<p>The cursor variable has a reference to the resolved object which is the Image named cursorArrow. We make the image visible and hide the real cursor. We must make the image &#8220;invisible&#8221; to mouse events so we set the IsHitTestVisible property to false. Finally, we register for the MouseMove event which is responsible for positioning the image wherever the mouse should be:</p>
<p> </p>
<pre class="brush: csharp; gutter: false;">
private void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
{
    if (!this.IsCursorNameSet)
        return;
 
    FrameworkElement cursor = Cursor as FrameworkElement;
 
    Point mousePosition = e.GetPosition(null);
    cursor.Margin = new Thickness(mousePosition.X + OffsetX, mousePosition.Y + OffsetY, 0, 0);
 
}
</pre>
<p>To position the image, we use the trick of specifying the top and left values of its Margin based on the current mouse postion and the OffsetX and OffsetY dependency properties we defined.</p>
<p> </p>
<p>In the MouseLeave event handler, we simply undo what we set in the MouseEnter handler.</p>
<p> </p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/102709_1407_HiddenObjec5.png" alt="" /></p>
<p> </p>
<p>I&#8217;ve seen a similar approach to custom cursors various places on the Internet. One requirement that I had was the need to specify a cursor at the UserControl level as shown, but then to have a child (or grandchild, etc.) object of that UserControl also have a unique cursor. If you move the mouse over a hidden rectangle on the left side of the screen the cursor will change to a left-facing arrow. Clicking the arrow will take you to another screen which has a hidden rectangle on the right that displays a right-facing arrow to get you pack to the original screen.</p>
<p> </p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/102709_1407_HiddenObjec6.png" alt="" /></p>
<p> </p>
<p>In the code, I created two path objects for the arrows just to show that any element could be used for a cursor. If I wanted, I could even have a cursor with multiple objects grouped in a Canvas that use animation storyboards.</p>
<p> </p>
<p>When you look at the complete source for this project, you will notice that I use a Stack data structure to keep track of the nested cursors. I am not completely satisfied with the code as it stands, but it works for the present situation. Two things to note. First, the hidden rectangle must have space all around it so that the cursor properly changes from the left arrow to the cursorArrow. Second, I had to do a workaround because the shapes generated from the ParticlesBehavior was interfering with the custom cursor as sometimes a MouseEnter event was being fired with the star shapes but no MouseLevent event.</p>
<p> <br />
Check out the code and let me know if you come up with a better solution.</p>
<p><a href="http://www.shazaml.com/downloads/ClutteredCubeSource12.zip"><img class="alignnone size-full wp-image-319" title="Zip" src="http://www.shazaml.com/wp-content/uploads/2009/10/Zip.png" alt="Zip" width="93" height="96" /> Source Code</a></p>
<p><a href="http://www.shazaml.com/hidden-object-episode-12-demo"><img class="alignnone size-full wp-image-320" title="silverlight" src="http://www.shazaml.com/wp-content/uploads/2009/10/silverlight.png" alt="silverlight" width="93" height="96" /> Demo</a></p>
<p>In the <a href="http://www.shazaml.com/archives/hidden-object-episode-13">next episode</a>, we will add a hint feature that allows the player to see an area of the screen that still has an object to find.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shazaml.com/archives/hidden-object-episode-12/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
