@ksmarshall – i <3 software

PAGES

23

Dec 10

WP7 Camera Access–Flashlight, Augmented Reality and Barcode Scanning



[Download Code]

In a special holiday post my gift to you is not one, not 2, but 3 windows phone camera tricks. It’s a mobile ménage à trois.  

1,,) Flashlight

There are lots of those flashlight apps in the marketplace that take about 2 minutes to build. This also took 2 minutes to build but it’s way better because it uses the real light on your phone. (Note: It’s turning on camera recording, but not actually saving anything when it’s done. Not sure what that will do to memory usage if you wonder through a cave with this as your flashlight. Might need to turn it off occasionally)

2) Barcode Scanning

Uses zxing. There was a Silverlight port linked somewhere that I used. Seems to work well for QR codes.  Not so well for other stuff.  The code in there right now should just work. You can use zxing generator to test it out. I’d like to get the 1D barcode scanning to work, but I didn’t have time to see what’s the problem right now.

3) Augmented Reality

Uses the awesome SLARToolkit by René Schulte. Basically his hello world augmented reality app running on the phone. You can use this marker to test it out.

You should just be able to run the xap in the debug folder to try all of this out.  The code is all pretty simple, but a few people have asked about barcode scanning and AR so this should get you started.

If you want to build yourself you need to do a few things since I put the Microsoft.Phone.Media.Extended dll in the GAC.

1. Copy Microsoft.Phone.Media.Extended.dll to C:Program Files (x86)Reference AssembliesMicrosoftFrameworkSilverlightv4.0ProfileWindowsPhone

2. Open C:Program Files (x86)Reference AssembliesMicrosoftFrameworkSilverlightv4.0ProfileWindowsPhoneRedistList FrameworkList.xml and add the line

3. Open a visual studio command prompt and go to C:Program Files (x86)Reference AssembliesMicrosoftFrameworkSilverlightv4.0ProfileWindowsPhone  and type “sn -Vr Microsoft.Phone.Media.Extended dll”

Obviously you’ll need a copy of the Microsoft.Phone.Media.Extended dll.  You can get that from the rom on your phone or from a rom that someone else dumped. 

If you want to build your own app using the camera, make sure to add       to the capabilities in the manifest.

Also I think I contractual obligated to say this, but using the camera in this manner will not pass marketplace certification unless you also include a healthy bribe with your xap.

1 comment , permalink


7

Dec 10

WP7 Tip–Pseudo Map Launcher



[download code]

WP7 has a several built in launchers, but the map app does not have one. It’s unfortunate because I think it’s fairly common that you’d want to have a link to get directions in a mobile app since you are, you know, mobile.  Right now the best way to do that is to basically recreate the map app inside your app using Bing/Google maps to get turn by turn directions and the SL Bing maps control. There is one other alternative I found:

var task = new WebBrowserTask();
task.URL = “maps:1%20N%20Franklin%2060606″;

or

//task.URL = “maps:37.788153%2C-122.440162″;

task.Show();

That sort of approximates the behavior of the map launcher in the native apps like IE. The downside to this is that it requires 2 back button presses to get back to your app.  It also inserts that page into the IE app history. It’s not ideal, but neither is trying to recreate the map app inside your own map app.  I wouldn’t really recommend this approach, but it’s there if you really need it.

Extra credit:

Try playing around with the search/web tasks to see what kinds of other hidden launcher functionality you can find.

1 comment , permalink


7

Dec 10

WP7 Tip – Beware the 15 App Push Notification Limit



Maybe most people knew this, but I didn’t – WP7 devices can only have a total of 15 apps registered for push notifications per device.  If the user installs 15 apps that use push notifications and your app is the 16th one installed, you’ll get a InvalidOperationException(Channel quota exceeded). 

The important thing here is to just handle this and alert the user that they should uninstall one of the other less cool apps that is using up a valuable push notification slot. 

This sucks though, right?  I get that it’s v1 and there are limits, but 15 seems a little low especially considering how Live tiles are heavily touted in WP7 marketing.  Is this widely known? Do devs handle this error and alert the user?  If people are complaining about push notifications not working in your app are you aware this could be the issue?

My primary complaint is how the OS handles the user experience.  No where does it tell the user how many apps are using push notifications and there is no central place to disable notifications for applications to free up a slot.  Plus the certification guidelines only require that apps allow turning on / off toasts, not live tiles.  So basically if an app is using a live tile, you need to uninstall it to free up a notification channel once you have 15 apps using them? It seems like there needs to be an API to see what other apps are installed so you can alert the user like “I see you’ve got two weather apps installed that use push notifications. How about you do me a favor and uninstall one of them so I can spam you with toast messages please. kthxbai”  I suppose the response is that a,,) most people don’t use more than 15 apps with push notifications b) you can update tiles without push notifications and c) there aren’t even 15 apps in the marketplace with push notifications

1 comment , permalink


18

Nov 10

WP7 Hack 001: Raw Video Feed and Augmented Reality



Just like title says – it’s using the methods in Microsoft.Phone.Media.Extended to access the raw camera feed and process some augmented reality markers.  FYI, the video sucks. I took longer to record this than I did to get everything working. It does actually work much better when I’m not trying to line up a web cam filming a phone showing video of a piece of paper in front of a monitor. 

 

Thanx to this thread, @ChrisWalshie and the SLARToolkit for doing 97.5% of the work. I tried invoking the non-public and native dlls awhile back but who knew you needed this empty WPInteropManifest.xml file? After seeing Chris’s tweets it gave me some motivation to try getting the camera and compass to work.  Ideally this would be accessible to everyone somewhere between now and really soon. Sometimes I think Microsoft doesn’t want developers to have fun on this platform.

And why does LG get access to this, but no one else does officially? Raw camera access and the compass are two of the 4-5*things you need to make some awesome phone apps like video chat, Facebook augmented reality view of places/friends, shiba inu mobile puppy cams, etc.  Instead all we get is LG Scan Search? Come on now, that’s ridiculous. LG should be on double secret app certification probation until they can build a phone that goes over 50fps** and renders colors within several shades of the hex values you specify.

Seriously, everyone needs to write a letter to their local Microsoft representative and demand some access  to all he cool APIs blocked for 3rd party apps.  That or whine about it on Twitter.

*coffee and cigarettes are right up there in the top 3 

**For real.  Check it yourself.  No way you will ever hit 60fps like windows phones are supposed to on a LG unless you solder on another GPU.

2 comments , permalink


3

Nov 10

WP7: Using LongListSelector and LowProfileImageDownloader for better scroll performance



[Download Code]

Scrolling is problem one of the biggest performance pain points for windows phone 7 development. I complain about it a ton (sorry phone team). Specifically for longer lists that involve images.  Even a simple list of images with text can make scrolling really, really sluggish. Some of the issues are probably on my code, but I also think the runtime could use some performance enhancements.   David Anson posted some good code around using a image downloader to offload work to a background thread. The major issue is that images are downloaded on the UI thread which is also the thread handling your touch input & rendering.

As you can imagine, the phone’s limited CPU can’t keep running at 60fps with all that going on.  The image downloader helps, but you can optimize it further.  In a list, you can avoid downloading images while the list is scrolling.  You can also clear the queue and not bother to download images that you are quickly scrolling past.  You can also sleep/throttle the downloads to lessen the impact on the UI thread.  One thing you lose through the downloader is caching.  You can cache in memory or to iso storage.  Caching the bitmap source in memory makes future retrieval really fast.  Just make sure you limit the cache size so you don’t exceed the 90MB limit for apps.

The long list selector also helps scrolling a lot even for flat list that don’t need the the selector functionality.  (It also adds header / footer support while maintaining virtualization which is nice if you need a “get more” button at the bottom or to scroll the pano item title with the list) The long list selector uses it’s own virtualization which avoids some issues that listbox/vsp has.  It also seems to have visually smoother scrolling (Touch seems a little flakey in places though – doesn’t always stop immediately and sometime drops the first flick when it’s not scrolling. Once you get it going though, it scrolls pretty smooth).  Another big bonus is being able to adjust the buffer size.  Normally listboxes with virtualizing stack panel buffer 3 screens.  If you pan through a page then end in a flick you will use up most of the buffer which seems to cause that flash of no content.  The LLS helps you work around this behavior based on your list needs.  Finally it has simple events for detecting scrolling start/stop so you can adjust when you do work like downloading images.

So based on David’s image downloader / twitter sample, I made some changes and switched to the long list selector. 

  • Images are cached in memory after they are fetched for faster retrieval in the future.
  • The background thread pauses while scrolling to avoid calling back to the UI thread and disrupting performance
  • Images are not downloaded while scrolling.  They get queued and only ones that are in the on screen buffer get added to the request queue.  Pending requests outside the buffer are cleared. 
  • I just avoid downloading images until you are stopping to look at a screen.   You could make some tweaks to just keep fetching until every image is downloaded, but I prefer to have the phone not do more work than is absolutely necessary
  • I use a custom control in the list item which is somewhat debatable.  I like to think that cutting out some binding and not parsing a template is slightly faster than the alternative.  it’s a little hard to test without a profiler though.

I tried some other techniques to further minimize how much is downloaded like only fetching ones in the actual viewport. The code to actually find what is in the viewport causes more harm than good because of the amount of time it takes to calculate the bounding boxes even if you use a binary search on the visual children of the list.  There is a method in the LLS to get items in the viewport, but that does not give you the containers to find the items to load images for. I also experimented with caching stuff to iso storage. I’ll post another one later when I get a chance.

So tryout the code. I think long list selector is a good replacement for most listboxes. Just keep in mind that like most code i post,  it’s just a quick prototype I hacked together from some other various code and it’s not tested thoroughly. Use it to get some ideas, but you will need to do some work on your own to make sure it’s production ready.

0 comments , permalink


3

Nov 10

WP7 Serialization Comparison



[download code]

A few people asked about binary serialization in my last post.  Here is a small sample app that shows how to do it.  It also shows you the difference between the different serializers you can use: binary, Json.net, DataContract and DataContractJson.

You really have to run it on the phone to see the the difference.  The emulator is so much faster that the results are fairly close unless you have a ton of objects.

 

serialization

 

This is mostly focused around persisting data to isolated storage for caching.  Since most apps load it on startup and write on shutdown, it needs to be reasonable fast.  The differences might vary a bit depending on the # of objects and the complexity of the object graph, but binary serialization is going to be way faster almost every time.  Even serializing settings to a file is faster than using isolated storage application settings (for that test i took into account the time it takes to actually grab an instance of the settings otherwise the time to pull a setting out will basically be 0ms.  I only did 5 strings, but if you have a lot more or try to put non primitive data types in there, the speed difference will be even more dramatic)

Regarding the binary serialization, you can just look at the code.  I have some helper extensions in there.  The main points to keep in mind are:

  • You have to read / write in the same order otherwise you will have some unexpected values or junk objects coming back.
  • To write a list out, just make sure you write the count first so you know how many loops to read through.
  • If you are writing out an object, you can just write a bool if null or not first, then write the object out
  • For strings you should either always write “” or just write a bool then string if you want nullable ones
  • Be really careful with versioning.  You should write the version number first and then run different serialization paths based on the file version if you need to add / remove properties later

In summary:

  • Binary serialization is a much faster method of persisting data for tombstoning or between launches
  • If you are consuming a Json based web service, use Json.net. The DataContractJsonSerializer is significantly slower.
  • Consider not storing settings using the built in iso storage settings object if you want to squeeze every last bit of performance out of the phone
  • (thanks to John from IdentityMine for that tip)

5 comments , permalink


27

Oct 10

WP7 Development Tips Part 1



Performance is the area that we probably spend the most time on in all our apps. Building apps on the phone is just way different than building desktop apps. Things that might be really minor optimizations on a desktop Silverlight can really make a difference on desktop Silverlight apps.

Developing on the phone is an issue of economics where processing power is a scarce resource. You have to be conscious of the tradeoffs of using things like binding, layout controls, dependency injection, etc with their impact on performance. When I first started building phone apps I was excited to use nRoute and it’s nice features around MVVM/Resource Location/Messaging/Navigation. I wanted to have this really perfect loosely coupled architecture that used biding for everything/minimal code behind, had great designer support and dynamically resolved the proper services and models. In practice, that is not generally high performance code on the phone. If you are using some extra frameworks, really be conscious of the impact on performance and decide if you really need that architecture. What might work wonderfully on a more complicated desktop line of business app might not work as well on the phone. You just have to expect to write more optimization in a mobile app regardless if it’s the iphone, wp7 or android.

Silverlight was billed as “same Silverlight, just on the phone”. That is mostly true in terms of the api, but not necessarily true in terms of the actual runtime. It’s really a brand new runtime based on Silverlight 3 with some extra features added, so certain pieces of code might not have the same performance characteristics.

I’ve seen a lot of articles from various other people that talk about “buttery smooth scrolling” and other performance tips. At times the tips are a little too generalized. When you try to optimize something for performance on the phone, you really need to take into account your specific circumstances and find the right combination that works for your app. Always test and benchmark. Some things are more difficult to measure without real profiling tools,but do the best you can. Also be aware that scrolling in 3rd party apps on the phone is just not great at the moment. The native OS apps use a different UI framework that is going to make all but the simplest 3rd party apps feel sluggish so don’t feel too bad if your app scrolling seems slower. It’s probably not entirely your fault. Although this guy (around 8:50) seems to disagree. Sure 3rd party apps will get better with more experience and time,but the runtime needs to also get better. It’s the v1 of a new platform for everyone.

Finally, most of my thought are based around apps like twitter or facebook or other apps that require lots of live network data and have more complicated/longer list based screens. A 2 screen unit converter app is just going to be faster because it’s a simpler app and you don’t really need to optimize much.

So here are some things that you can try think about for your application:

  • Data binding is always going to be slower than just directly setting a value. If you don’t have to databind, try to avoid it. I see lots of people going out of their way to MVVM everything and create bindable app bars. Feel free to just wire up a handler once in awhile or just directly set some text. There are other ways of centralizing code for reuse instead of trying to adhere to a strict pattern. If you are trying to animate in a screen and data bind simultaneously, most of the animations will get chopped. Just directly set enough pieces of data to have something to animate in and then you can do more intensive data binding after the animation is complete.
  • As mentioned above – consider the tradeoff of always following the same pattern just for the sake of maintaining the pattern. Sure it might be easier to maintain, but high performance code doesn’t always look pretty. Be flexible, take shortcuts and do what makes sense for a specific part of the application. That’s not to say you should ever write bad code, just don’t focus on creating an architectural masterpiece in lieu of something that is performs well. The end user only sees what you put on screen, not the code behind it. They don’t really care that you used MEF and have an awesome messaging framework. When i see people over-engineer what should be a simple app just to adhere to some theoretical best practices I get sad.
  • Converters slow your app. It’s better to just create the specific properties needed on your model. It’s minor optimization, but it adds up on the phone.
  • Template expansion is slow. If you have a listbox where the item templates have lots of visibility converters, it’s going to be inefficient for a few reasons. First, you pay the perf hit of parsing a template for an item that is just going to be collapsed anyway. Plus you ran it through a bound converter which is slower. To optimize better you can do a few things:
    • If you can cut down visuals in a list, that is always the first place to start. If not every item in the list can use the same fixed template, consider making the list more of a summary and then link to a detail screen. The Twitter app does this nicely to avoid parsing hyperlinks in the text or showing attached photos. (because of how virtualizing stack panel works, it’s always better to have fixed height items that use the same template) Facebook on the hand parses text for hyperlinks which is slower because it need to reassemble the text in a wrap panel of multiple controls and the regexing is slow, but that is more in line with the user’s expectation of the facbeook experience.
    • If you have to have variable templates, make the list item a custom control and have the control dynamically create specific visuals needed for the list item so you don’t do extra layout work. Plus you eliminate converters and other extra data binding since you only have to bind one data property. Creating in code is faster than parsing the extra xaml. Obviously this comes at a maintenance penalty and you don’t get designer support, but for those of us that don’t use blend or the designer view, not so much of an issue. Although inside your control you need to keep references to UI elements that you create and reuse as your entire control is recycled BY well, “same, your, your, soon, the, mentioned, much, it, much, possible, far, you, a, your, well, long, they, much, possible, many, you, soon, possible.endering data that might not be needed. Another option is to add a load more button at the bottom of the list.
    • It’s really important to minimize work on the UI thread as much as possible since the touch recognition happens on the UI thread and will get dropped if the processor is maxed out. Don’t do anything on the UI thread that is not directly related to setting / manipulating a UI element. Well you can do some things, but really try to background as many chunks of work as you can.
    • Some apps like the people hub scroll the header with the list and have a footer. If you try to retemplate listbox and insert a header and footer around the itemscontrol inside the scrollviewer, you will lose virtualization. There are a few ways you can accomplish this while maintaining virtualization.
      • Easiest is to bind to a list/collection of object and insert dummy items for the header and footer. You can then inherit from listbox and make you own that has a template property for header and footer. In PrepareContainerForItemOverride you can check if it’s a header / footer object and apply the right template.
      • If you don’t want to create all these collections with dummy objects, you could internalize the collection to you own listbox. Instead of binding your normal collection to itemssource, add a new proprty called datasource, bind to that and hook into the collection changed events to mirror the changes in your own internal collection. Then you can bind that internal collection and add your own header / footer items to the collection. This also allows you to easily add some “Loading data” message or “No data” message.
      • Talking to some other people, I have learned that this might not be very performant because it breaks some of the container recycling. The alternative is to not override PrepareContainerForItemOverride and instead have one template and change the visibility on the non header/footer items. This is one of those things that you have to try out and see for yourself.
    • Focus in making the app respond to input as soon as possible. You need to do something immediately when the user takes some action. If the content will take some time to load, at least transition to it and display a loading indicator. An example would be a popup that slides in with a list of items. If the list is somewhat complex and does not render immediately, there ill be a noticeable lag between the user action and the response. Slide up the list with a header and loading indicator, then data bind the list. It will feel more responsive.
    • I wrote previously about transitions. You should design the app with transitions in mind and be conscious of why certain animations are useful for context and perceived performance. It does seem like this should be easier to do since animation is a big part of the metro design.
    • Spend some time to review the hit targets of your elements. 40×40 seems to accommodate an adult finger reasonable well. Remember to keep a reasonable mount of spacing between hit areas. You really need to think about this when designing an application. With a mouse you can click on a specific point. On the phone you need to account for the size of your finger. You want to avoid having users click the wrong things, navigating to a screen , then having to navigate back.
    • If you have a pivot with 4 items and you save the selected index on tombstoning you can’t always set the selected index immediately in OnNavigatedTo. The pivot creates the first, 2nd and last items. Setting the selected index to the 3rd pivot will throw an exception. If you have more than 3 pivots and you need to set the selected index, grab the index of of the page state in onnavigatedto, store in a variable and set it in the page loaded event.
    • You can always check PhoneApplicationService.Current.StartupMode == Activated to check whether you are returning from a tombstone. The whole concept of tombstoning could be my least favorite #wp7dev feature besides the navigation framework and scrolling performance. I really don’t understand why this is something developers should have to worry about. If the phone wants to tombstone my app, put it back the way it was when you’re done. Also be aware when launchers/choosers are going to tombstone your app or any other side effects when returning from them.
    • There are lots of different keyboard layouts (SIP). Use the right one for your text entry needs. You can optimize for web addresses, email, phone numbers, text (for dictionary suggestions) and search. One thing is that the search key is not super obvious in my opinion. You can use the app bar to augment the SIP by adding more specific buttons like upload photo, etc.
    • There is currently no socket support so implementing something like a chat client is difficult. *cough* facebok chat *cough *
    • If you want your pages to load quickly, don’t do anything before the first layout updated event after loaded is fired. Then defer loading things until they need to be shown.
    • There is no launcher for the bing maps app. If you want to display driving directions you need to call the virtual earth web service to get the data (or whatever other map service you might prefer)
    • There is also no compass api, no direct camera access (so therefore no augmented reality unless you are a handset maker like LG and have native code access), no Bluetooth api, no ability to add events to the system calendar, no video chooser (thus no ability to upload videos in your app), no ability to customize alert dialogs to match your app if you opt out of theming, no ability to run in the background (you can have your app run under the lock screen though), no copy paste (coming soon and hopefully 3rd party app support), no ability to alter the back stack, no gif decoding support (try ImageTools if you need to display gifs). I’m probably missing a few things that i would like to use but are not not supported. Despite all that, I’d still rather use visual studio / c# than Xcode/obj-c I do think the silverlight team did a great job getting it on the phone. It really is one of the better frameworks for building UX centric apps and the silverlight team has been really helpful in tracking down issues we’ve encountered.

    I’ll be at PDC if anyone would like to chat about #wp7dev

    17 comments , permalink


13

Oct 10

WP7 – Page Transitions Sample



I posted a few methods for doing page transitions in the past that were based on some older versions of the SDK and don’t work anymore. In the post I’ll go over another method which uses a base page to handle all transitions.

[Download Sample]

Before going into the code, here are some thoughts I have on page transitions and animations on the phone in general:

  • Animations are a key part of the metro experience. With the focus on text and minimal chrome it’s important to add animations to make the UI have some life. They also “surprise and delight the user” as the Metro marketing material would say.
  • Aside from the visual wonder created by animations, they also server some other purposes:
    • The type of transition conveys meaning: The continuum animations provide context when drilling into a detail screen or task, sliding animations signify the creation of something new, etc. Matching the way the OS does transitions makes your app seem intuitive and it can conveys ideas without taking up the limited space on a mobile device.
    • Transitions can improve perceived responsiveness of the application
  • Don’t over -animate.
    • Avoid long, gratuitous animations just because you can easily create storyboards in xaml. The native apps use some well thought out, subtle animations so try to follow that example for UX consistency. The timings on the native animations are fairly short – usually less than 350 ms. If you have much longer animations you are probably doing something that is going to look weird and make the app seem slow (some exceptions are the pano slide in animation which is around 1 – 1.5 seconds and the feather might have a longer total duration depending on the amount of items that feather in/out).
    • Animations should enhance the user’s experience, not become distracting or annoying.
    • If something needs to rotate out like a turnstile, you don’t actually have to rotate a full 90 degrees. You can just rotate partially and then change the opacity to 0. Your mind will fill in the missing part of the animation. Cutting the amount of time actually animating frees the phone up to load the new UI while it appears that you are still animating. Look carefully at the native app transitions. They actually animate less than you probably think and use somewhat simple storyboards. For example the turnstile animation is somewhat close to forward out: 0 to 50 and forward in: –80 to 0. In summary, use animations to help create the illusion of performance.
  • When animating between pages, it’s really important that the pages load as fast as possible. There are a few ways to do this:
    • Minimize code in the constructor and loaded event. Ideally you should do nothing until the animation is complete.
    • Data binding is really slow on the phone and lots of it will just cut any transition. Try to not databind until after the transition is done. For example, pass data in the querystring from the previous page and set it directly on the next page. You want to have some visuals on the page to transition to,but just enough so there is something to actually transition to. If you need to fetch more data,do it after the animation is complete. Keeping lean xaml will help the page load faster.
    • Image downloading / decoding just hammers the UI thread. It’s going to be hard to animate a page in smoothly if you are setting some giant background image from a url.
  • Make sure your animations run on the compositor thread. This is covered in detail in the Creating High Performing Silverlight Applications for Windows Phone. So just to be clear, if part of your storyboard does something that is not supported on the compositor thread, then your storyboard will not run on the compositor thread. (I could be wrong on that point, although it seems to be the case)
  • Pick an easing function and stick with it. There are several easing function to choose from, but it looks weird if you start to mix and match. If you use exponential easing (and you should since that is the closest approximation to what the native apps do), just use that and vary the mode, duration, timing. Obviously you should use some type of easing if you want avoid an oddly robotic looking transition.

Since transitions are so important on the phone it would be great if future versions of the wp7 sdk included some prebuilt animations and events that would help actually running the transitions. At least that is what I’d prefer. Since that doesn’t exist I created a little helper framework that allows me specify a type of transition with the right elements when a page is about to navigate.

Types of animations on the phone

The phone has 4 animation directions: forward in, forward out, backward in, backward out. So if you transition to a page and click the back button, you need to have the reverse animation or at least something different that what you did on the way in.

The types of animations are:

turnstile

The default animation you see when an app launches and rotates in or when switching between tasks (choosers, launchers, certain pages)

When to use

Switching context from one task to another like opening a map for directions or when switching from one page to another that is not really a drill down detail or continuing context

Approximate storyboard

forward in: rotate on y-axis from –80 to 0 for 350ms, exponential out(exponent 6)

forward out: rotate on y-axis from 0 to 50 for 250ms, exponential in (exponent 6)

backward in: rotate on y-axis from 50 to 0 for 350ms, exponential out(exponent 6)

backward out: rotate on y-axis from 0 to -80 for 250ms, exponential in(exponent 6)

Notice the difference in timings and easing mode on the forward out of one page to the forward in of the other page. You don’t have to animate to from 90 to get that turnstile effect. Switching the easing mode creates the illusion for the swinging effect. As mentioned before, it’s really important the next page loads quickly so it appears to be one continuous motion. By not animating the full 90 and animating toward the outside portion of the viewport your mind should fill in the missing parts of the animation (the rest of the rotation that you would see and the part of the rotation that would be off-screen anyway) giving you almost a second to load the next page.

turnstile feather

The turnstile feather is basically like the turnstile except that list items each rotate out in succession. The start menu list on the phone does a turnstile feather to launch an app.

When to use

Same place as the turnstile, but for pages that are lists.

Note: This is probably obvious, but the transition out from one page should match the transition in on the next page. So don’t turnstile a page out and slide the next one in. That is just awkward. Although you can pair a turnstile with a turnstile feather since they are similar.

Approximate storyboard

forward in: rotate on y-axis from –80 to 0 for 350ms, exponential out(exponent 6)

forward out: rotate on y-axis from 0 to 50 for 250ms, exponential in (exponent 6)

backward in: rotate on y-axis from 50 to 0 for 350ms, exponential out(exponent 6)

backward out: rotate on y-axis from 0 to -80 for 250ms, exponential in(exponent 6)

Each item turnstiling out is delayed 50 ms from the previous one. It also looks cool if you save the selected item to last when you animate out. The start menu does this.

continuum

The continuum animation is used to create a sense of continuing context from one screen to another. The music + videos app does this when you click one of the initial menu options like “music” or “podcasts” and the text animates to the secondary page to become the title.

When to use

Lists of summary info like a name that when clicked go to a detail screen. Task menu options that become the pivot title of the next screen.

Approximate storyboard

The continuum animation is a little more complex than a storyboard. It has some code that creates a copy of the selected element so it can move without fading like the rest of the page.

Basically it’s something like:

forward out: the selected item drops 73px and slides 225 over with an expo ease in(exp 3 or 6) over 150ms. Page slides down 70px and the opacity goes to 0 with the same easing and time.

forward in: the page slides up 50px with and expo ease out over 150ms. The continuous element slides down 70px and over 130px with the same easing.

backward out: whole pages slides down 50px, expo ease in over 150 ms. The opacity also goes from 1 to 0. The native apps like the marketplace have a slightly different style where the continuous element slides and fades, but the whole page does not. Adjust to your liking.

backward in: The element that animated out slides in from –70px to the left with an expo ease out over 150ms

slide

The slide animations slide/fades some content over the existing content. This is used in the native apps to signify the creation of something new.

When to use

Creating or adding new items in your app. You can slide up/down left right. Whatever works for your layout. If you use separate pages, you can still slide, but the effect isn’t as good. Ideally the sliding element would be a control so it can be in a popup. In the attached example i use a fake popup that is just an element on the frame. There are 3 reasons for this:

  • Animations on popups don’t seem to be on the gpu
  • Sometimes i want the popup to handle both orientations and it’s easier if it’s in the frame.
  • If you have larger input boxes, an element in the frame will handle scrolling better to accept input. The SIP doesn’t work the same on popups vs elements in the frame.

Approximate storyboard

forward in: 150 (left, right, up or down), exponential out(exponent 6), 350ms, opacity 0 to 1

backward out: 150 (left, right, up or down), exponential in(exponent 6), 250ms, opacity 0 to 1

rotate

Rotating is used to change orientations form landscape to portrait. David Anson has a good post on this. Otherwise the UI should rotate from 0 to +- 90 over 500ms using exponentialeaseInOut. the rotation angle should be counter to the direction hat the device was rotated.

The easing exponents might have to be adjusted. Most of the ones that are 6 could be 3. If your app lags a little between page navigations you might not see animations with an exponent of 6 clearly.

For all of these storyboards you can just look in the code.

Code

This sample uses a base page. The reason I used a base page instead of a frame is because i wanted more control of animating actual elements on the page. In general the base page cancels all navigations, does some animation and recalls the navigation method that was originally passed. The base page requires some animation context for a page (usually layoutroot, but depends on your app)

The base page adds two overrides, GetAnimation and AnimationComplete. GetAnimation lets you specify and animator like continuum or turnstile based on a direction and uri of the next page. AnimationComplete let’s you reset some things on back navigation. Ideally you would just databind on forward navigation and reuse the page from the back stack on back navigation and only do binding on forward navigations. Not doing any work before AniamtionComplete allows you to have smoother, uncut page transitions. Otherwise you are fighting for cpu/gpu time.

So it looks like:

        protected override GetAnimation(AnimationType animationType, Uri toOrFrom)        {            if (animationType == AnimationType.NavigateForwardIn)                return new TurnstileFeatherForwardInAnimator() { ListBox = List, RootElement = LayoutRoot };            else                return new TurnstileFeatherBackwardOutAnimator() { ListBox = List, RootElement = LayoutRoot };        }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

        protected override void AnimationsComplete(AnimationType animationType)        {            switch (animationType)            {                case AnimationType.NavigateForwardIn:                   //set data contexts                    break;

                case AnimationType.NavigateBackwardIn:

                    AnimationList.SelectedIndex = -1;                    break;            }

            base.AnimationsComplete(animationType);        }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

By default if you just inherit from the base page and set an animation context in the constructor, it will turnstile those pages.

The base page model might be a little more intrusive, but we’ve already been using base pages to centralize a lot of common logic we are doing like saving state.

This is definitely a work in progress and could be more efficient, but I wanted to post something since some people seem to struggle with getting started with page animations. Contact me if you have any thoughts.

11 comments , permalink


6

Oct 10

WP7 – Quick Jump Grid Sample Code



[Download Sample]

With the recent release of the windows phone 7 toolkit, most of the controls in the native apps are present except the quick jump grid and the list picker. For those of you that don’t know the quick jump grid is described in the official design template.

QuickJumpGrid_PSD1

QuickJumpGrid_PSD2 QuickJumpGrid_PSD3

My co-worker Erik Klimczak blogged about one awhile back but never released the code so I thought I’d post an update. Here are some screenshots:

image

image

image

image

The sample control handles both the alphanumeric tiles and full text ones. There are a variety of properties to change any of the colors used, but it will default to the appropriate phone theme colors. The animations and styles should be fairly close to the native quick jump grid.

Couple of notes:

  • This is just a sample so the code could definitely be improved but it’s worked pretty well in the testing I’ve done. Feel free to take the code and make it better for your own use. This is also an older version that doesn’t support observable collections. I have updated an one that does support them but I don’t have it packaged as code I can share at the moment. It’s really not that hard to implement though. You just need a listener on the datasource and update the internal collection appropriately. I’ll release a cleaned up one as soon as I finish some other projects.
  • If you run it in the emulator, the animation is slightly lagged. This is an odd instance where the animation on the phone is actually faster than in my emulator. It’s almost always the opposite case for me even with the GPU acceleration on the phone. It’s actually pretty smooth on the phone I think despite the code for the animation looking like a mess.
  • I used some classes from the Silverlight Toolkit, but you could drop those and just use the ones in the toolkit if you already referenced that in your project. I just pulled out the stuff i needed to make it more compact
  • I tried a variety of options for setting the filtering and ordering properties like using some sort of collectionviewsource or dynamically creating linq expressions from some bindable fields, but I ended up using a method similar to one of David Anson’s blog posts which seemed to be the most flexible.
  • The overlay will close on back key press and cancel the page navigation, but if you are handling the back key press in the page to do animation you will have to check to see if the overlay is open since the page will handle that event before the quick jump grid has a chance to handle it.
  • I recently saw this other version on codeplex – http://bewisephonecontrols.codeplex.com/ so you may want to try that out also and see what works best in your app

1 comment , permalink


21

Jun 10

Powermote: WP7 remote control for PowerPoint



This is a preview of a quick app I built for Windows Phone 7 to remotely control a PowerPoint presentation from a WP7 device.

The app consists of a PowerPoint add-in that hosts a WCF service. The add-in creates a ribbon menu item to connect to the phone. Clicking “Connect to Phone” sends a push notification to the phone via the Microsoft Push Notification Service. The phone then sends a request to the WCF service hosted in PowerPoint to request data about the presentation along with URIs for the slides images that the add-in saves out as thumbnails. It’s definitely easier to build office add-ins with VS2010 and Office 2010.

 

image

On the phone you can use a swipe gesture or the buttons to change slides . It also includes a timer and displays the notes for the slide. Here is video of the application controlling a presentation.

 

[ higher quality video]

I have several other applications in the works that have a similar model of WCF services and push notifications. One is for remotely controlling media center (or streaming media center content to the phone) and the other is a collection of browser add-ins that push links to the phone and hyperlinks phone numbers to enable dialing through the phone from your desktop.

0 comments , permalink