Navigation


Markus on Development and Publishing

This is Markus Egger's professional blog, which covers topics such as development, publishing, and business in general. As the publisher of CoDe and CoDe Focus magazines, and as the President and Chief Software Architect of EPS Software Corp., Markus shares his insights and opinions on this blog.

Content Area Footer

Thursday, December 02, 2010
Taking Screen Shots of Windows Phone 7 Panorama Apps

I recently encountered an issue with taking screen shots of Windows Phone 7 apps that quite stumped me (and required help from my Microsoft friend Jared Bienz… thanks!): I needed to take a screen shot of a Windows Phone 7 Panorama app (which happened to be a very first version of our CODE Magazine Windows Phone 7 application). What I tried to accomplish was a panorama shot that showed all the panels of the panorama like Microsoft often shows it in promos like this one:

So when I needed to create a similar screen shot myself, my first thought was “I will simply launch the app in the emulator, take a screen shot, then slide to the right, take another screenshot,… and then stich the individual images together”. Unfortunately, this does not work as such, because the panel doesn’t just slide left and right. Instead, it performs “parallax scrolling”, which means that different parts of the panorama scroll at different speeds. The title (“people” in the example above) scrolls slower than the main content for instance. This provides a very nice visual effect, but it also means that individual images don’t just line up when you take screen shots individually and then stitch things together. Bummer.

As it turns out (and by that I mean “as Jared figured out”), the whole panorama actually uses some sub elements (namely PanningTitleLayer and PanningBackgroundLayer) which inherit from PanningLayer. PanningLayer has a property called PanRate, which defines at what rate each individual panel scrolls. In theory, we could just set these properties to 1 and thus have everything scroll at the same speed and could take individual screen shots and stitch them together. Unfortunately, things aren’t quite that simple, since that particular property is a protected read-only property. Hmpf!

To get around this, we can subclass the two panning layers and override the property like so:

public class NoParalaxTitleLayer : PanningTitleLayer
{
    protected override double PanRate
    {
        get { return 1d; }
    }
}

public class NoParalaxBackgroundLayer : PanningBackgroundLayer
{
    protected override double PanRate
    {
        get { return 1d; }
    }
}

Now we have elements that would scroll properly if they were only used somewhere, which they are not. To fix that, we have to create our own style and template for panorama controls:

<Style x:Key="NonParalaxPanorama" TargetType="controls:Panorama">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="controls:Panorama">
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
          </Grid.RowDefinitions>
          <local:NoParalaxBackgroundLayer x:Name="BackgroundLayer"
                 HorizontalAlignment="Left" Grid.RowSpan="2">
            <Border x:Name="background"
                    Background="{TemplateBinding Background}"
                   
CacheMode="BitmapCache"/>
          </local:NoParalaxBackgroundLayer>
          <local:NoParalaxTitleLayer x:Name="TitleLayer"
                 CacheMode="BitmapCache"
                 ContentTemplate="{TemplateBinding TitleTemplate}"
                
Content="{TemplateBinding Title}"
                 FontSize="187"
                 FontFamily="{StaticResource PhoneFontFamilyLight}"
                 HorizontalAlignment="Left"
                 Margin="10,-76,0,9" Grid.Row="0"/>
          <controlsPrimitives:PanningLayer x:Name="ItemsLayer"
                 HorizontalAlignment="Left" Grid.Row="1">
            <ItemsPresenter x:Name="items"/>
          </controlsPrimitives:PanningLayer>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Now, all that is left is to tell the used panorama to use the newly created style:

<controls:Panorama Title="CODE Magazine"
          Style="{StaticResource NonParalaxPanorama}">

What is cool about this is that although it was a bit of a pain to create this, we now have a style we can easily assign and remove. This way, we can create our application as always but quickly disable parallax scrolling whenever we want to take screen shots. To take the screen shot, simply launch the app in the emulator, then take a screen shot of the initial view. Then, pan right and take another screen shot. Copy/stitch the screen shots together in any graphics program (they will now align properly) and continue with the next panel until you run out of panels (or room… it may not make sense to do more than 4 or 5 even if your app has more panels, since the resulting screen shot is somewhat odd if you have too many panels).

Here is a screen shot of a very early version of the CODE Magazine Windows Mobile 7 application:

Click for a larger version...

Note: Click on the above image for a zoomed version.

Oh, and one more thing: You may notice that when you run your app in the emulator, you see performance numbers on the right side of the display. These are very annoying when you want to take screen shots. I just blogged about how to get rid of these here.



Posted @ 8:08 PM by Egger, Markus (markus@code-magazine.com)


 

 

 

 

 

 

 



My Twitter Status


    follow me on Twitter  


    Geo Caching
    Profile for MarkusEgger

    Syndication ng> RSS 2.0 RSS 2.0

    All My Blogs:
    My personal blogs:
    Dev and Publishing Dev and Publishing
    Travel and Internat. Living Travel and Internat. Living
    Other blogs I contribute to:
    Milos Blog (US) Milos Blog (US)
    VFPConv. Dev Blog (US) VFPConv. Dev Blog (US)
    VFPConv. Dev Blog (DE) VFPConv. Dev Blog (DE)

     

    Blog Archives
    All Blog Posts

    2012
        September (1)
        April (1)
        March (1)
    2011
        October (1)
        June (3)
        May (1)
        March (2)
        February (2)
        January (2)
    2010
        December (3)
        November (2)
        October (2)
        September (1)
        August (2)
        July (1)
        June (1)
        April (3)
        March (1)
        February (5)
        January (1)
    2009
        October (4)
        September (2)
        August (1)
        July (1)
        May (4)
        April (6)
        February (1)
        January (1)
    2008
        December (3)
        November (11)
        October (8)
        September (1)
        July (1)
        June (3)
        May (3)
        April (6)
        March (6)
        February (4)
    2007
        December (1)
        November (1)
        October (5)
        September (1)
        August (1)
        July (6)
        June (3)
        May (3)
        April (1)
        March (2)
        January (2)
    2006
        December (3)
        November (4)
        October (1)
        September (2)
        August (2)
        July (4)
        June (1)
        May (2)
        April (10)
        March (2)
        February (3)
        January (1)
    2005
        December (6)
        November (7)
        October (6)
        September (8)
        August (10)
        July (6)
        June (9)

     

     

     

    This Blog is powered by MilosTM Collaboration Components.