Windows Phone 7: Drawing graphics for your application with Inkscape – Part III: Backgrounds

EDIT: new Marketplace Requirements came to my attention: wallpapers are not allowed to have (partially) transparent pixels. I fixed this post.

Lately I have been working on a Windows Phone 7 application in my spare time. It has been a lot of fun but, I have to admit, there has been some frustration as well. The problems I ran into are caused by my unfamiliarity with WP7 (evidently), the strict requirements of the Windows Phone Marketplace and flaws in WP7.

Some of the requirements of the Windows Phone Marketplace concern the graphics:

Backgrounds

Application content, such as text and visual elements, must be visible and legible regardless of the phone theme. For example, if the phone theme changes from black background to white background, the text and visual elements of your application must be visible or legible.

Background art (optional), used in the Background panorama, 1000 x 800 pixels in size.

These are just the regular requirements; I left out the special (but obvious) rules concerning violence, weapons, drugs and adult related content.

There are a couple of sites that show you how to draw icons using Expression Design but since all the tooling for writing Windows Phone 7 applications is free and Expression Design is not I decided to take the free-way and used Inkscape to draw the graphics. Like Expression Design, Inkscape uses a vector format which is very convenient when you have to draw the same image at several sizes.

Resources

There are a couple of invaluable resources when exploring the possibilities, do’s and don’ts in WP7 design:

  1. UI Design and Interaction Guide for Windows Phone v2.0
    This guide provides a lot of guidance and clues that show how to get a feel for the WP7 experience. Read it!
  2. Design Templates for Windows Phone 7
    Although this zip contains mostly PSD (yes…) files it also contains a PDF with a quick overview of the provided templates and some hints.

Let’s draw a background

There are two types of background we’ll take a look at. The first one is an image that is used for regular application pages. I decided to try an mimic the new Info Support style that can be seen here.

One of the things you need to be aware of is that the user of the phone could switch to the light theme turning all text from light on dark to dark on la light background. So I wanted to make two versions of the same image.

Here we go:

  1. Start Inkscape and set the document to 480×800 (more about the size later) (See the posts I and II in this series for detailed instructions)
  2. Rename the current layer to Theme
  3. Add two sub layers to the theme layer, Dark and Light,
  4. Add a black rectangle to the Dark layer that covers the document.
  5. Add a white rectangle to the Light layer that covers the document.
  6. Lock all Theme layers. Now you can switch quickly between themes by hitting the Visibility icons
    image
  7. Add a top level layer that will contain the actual image.
  8. I used the Bezier tool to draw a triangle:
    image
  9. Next I adjusted the fill of the triangle:
    image
    Note the transparency, it is at approximately 33%. This is very important as you will see when you toggle between the Light and Dark themes:
    image
    The light theme causes it to be bright enough to have a good contract for dark text and the dark theme makes the triangle dark enough for light text.
  10. Next I used the Edit path button to rearrange the corners of the triangle:
    image
  11. Then, still using the Edit path button, I selected/clicked the side that goes from the top left to the bottom right and turned it into a curve:
    image
  12. Using the handles that appeared I shaped the triangle:
    image
  13. I copied the shape and moved the copy a bit and stretched it a bit wider:
    image
  14. Using the Edit path tool I selected the curve and hit the Insert node button:
    image
  15. I moved the lower right corner up and the added node down:
    image
    For the best results make sure Grid snapping is on.
  16. Select the bottom curve and hit the curve to line button:
    image
  17. Using the Edit path button I turned the bottom left hand corner in to a crisp corner and I adjusted the curve a bit:
    image
  18. By copying, rotating and adjusting the nodes of the copy I made this:
    image
  19. Time to save! Keep a copy of the SVG file in source control.
  20. Export a PNG file by opening the Export Bitmap dialog (File|Export bitmap…)
  21. Adjust the settings like this: 
    SNAGHTML6db56b
  22. Hit Export and you have made the dark version.
  23. Next make the White background visible and export a second png with a different name (e.g., Wallpaper_Light.png)

Using the Wallpapers

Using the wallpaper in a single page in your application is easy:

  1. Add the PNGs to a folder in the project, set their Build Action to Content and do not copy it to the Output folder.
  2. I added some logic to the base class of all my views:
    namespace Example.Views
    {
    public class PageBase : PhoneApplicationPage
    {
    public Brush WallpaperDark
    {
    get { return (Brush)GetValue(WallpaperDarkProperty); }
    set { SetValue(WallpaperDarkProperty, value); }
    }

    public static readonly DependencyProperty WallpaperDarkProperty =
    DependencyProperty.Register("WallpaperDark", typeof(Brush), typeof(PageBase), new PropertyMetadata(
    new SolidColorBrush
    {
    Color = Colors.Transparent
    }));

    public Brush WallpaperLight
    {
    get { return (Brush)GetValue(WallpaperLightProperty); }
    set { SetValue(WallpaperLightProperty, value); }
    }

    // Using a DependencyProperty as the backing store for WallpaperLight. This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WallpaperLightProperty =
    DependencyProperty.Register("WallpaperLight", typeof(Brush), typeof(PageBase), new PropertyMetadata(
    new SolidColorBrush
    {
    Color = Colors.Transparent
    }));

    protected bool IsLightThemed
    {
    get
    {
    var app = App.Current as App;
    return (Visibility)app.Resources["PhoneLightThemeVisibility"] == Visibility.Visible;
    }
    }

    public PageBase()
    {
    Loaded += PageBase_Loaded;
    }

    void PageBase_Loaded(object sender, RoutedEventArgs e)
    {
    ShowWallpaper();
    }

    private void ShowWallpaper()
    {
    var app = App.Current as App;
    if (app != null)
    {
    if (IsLightThemed)
    {
    if (app.RootFrame.Background != WallpaperLight)
    {
    app.RootFrame.Background = WallpaperLight;
    }
    }
    else
    {
    if (app.RootFrame.Background != WallpaperDark)
    {
    app.RootFrame.Background = WallpaperDark;
    }
    }
    }
    }
    }
    }

As you can see there are two wallpaper properties and after loading the page the page decides which one will be used as background.

I specified what wallpapers should be used in a style for my pages like this:

<Style x:Key=&quot;PageStyle&quot;
TargetType=&quot;views:PageBase&quot;>
<Setter Property=&quot;FontFamily&quot;
Value=&quot;{StaticResource PhoneFontFamilyNormal}&quot; />
<Setter Property=&quot;FontSize&quot;
Value=&quot;{StaticResource PhoneFontSizeNormal}&quot; />
<Setter Property=&quot;Foreground&quot;
Value=&quot;{StaticResource PhoneForegroundBrush}&quot; />
<Setter Property=&quot;SupportedOrientations&quot;
Value=&quot;Portrait&quot; />
<Setter Property=&quot;shell:SystemTray.IsVisible&quot;
Value=&quot;True&quot; />
<Setter Property=&quot;WallpaperDark&quot;>
<Setter.Value>
<ImageBrush Stretch=&quot;None&quot;
ImageSource=&quot;/Example;component/Resources/Wallpaper_Dark.png&quot; />
</Setter.Value>
</Setter>
<Setter Property=&quot;WallpaperLight&quot;>
<Setter.Value>
<ImageBrush Stretch=&quot;None&quot;
ImageSource=&quot;/Example;component/Resources/Wallpaper_Light.png&quot; />
</Setter.Value>
</Setter>
<Setter Property=&quot;toolkit:TransitionService.NavigationInTransition&quot;>
<Setter.Value>
<toolkit:NavigationInTransition>
<toolkit:NavigationInTransition.Backward>
<toolkit:TurnstileTransition Mode=&quot;BackwardIn&quot; />
</toolkit:NavigationInTransition.Backward>
<toolkit:NavigationInTransition.Forward>
<toolkit:TurnstileTransition Mode=&quot;ForwardIn&quot; />
</toolkit:NavigationInTransition.Forward>
</toolkit:NavigationInTransition>
</Setter.Value>
</Setter>
<Setter Property=&quot;toolkit:TransitionService.NavigationOutTransition&quot;>
<Setter.Value>
<toolkit:NavigationOutTransition>
<toolkit:NavigationOutTransition.Backward>
<toolkit:TurnstileTransition Mode=&quot;BackwardOut&quot; />
</toolkit:NavigationOutTransition.Backward>
<toolkit:NavigationOutTransition.Forward>
<toolkit:TurnstileTransition Mode=&quot;ForwardOut&quot; />
</toolkit:NavigationOutTransition.Forward>
</toolkit:NavigationOutTransition>
</Setter.Value>
</Setter>
</Style>

The style not only specifies the wallpapers but also the default transitions for the pages that I got from the Windows Phone toolkit

&#160;

Sizes

&#160;imageimage

As you can see in the screenshot the wallpaper is partially covered by the ApplicationBar. According to the Windows Phone 7 UI Design and Interaction Guide the height is fixed at 72 pixels. So is you know that all pages that will use the wallpaper show the ApplicationBar you could use a different size for the wallpaper (480×728)

The second kind of background is a background for a Panorama control. The guidance is a bit flippant. The Marketplace requirements state a size of 1000×800 but the UI Design and Interaction guide states:&#160;

Background images should be between 480 x 800 pixels and 1024 x 800 pixels (width x height) to ensure good performance, minimal load time, and no scaling.

Use a 16 x 9 aspect ratio for a panorama application that has four sections.

I am sticking to the Marketplace requirements because they need to approve the app.

Here is what I made:

IS_WP7_Fan_1000x800

Adding a background to a Panorama control is easy:

<Grid x:Name=&quot;LayoutRoot&quot;>

  <controls:Panorama Title=&quot;Title&quot;>

    <controls:Panorama.Background>
      <ImageBrush ImageSource=&quot;/Resources/wallpaper_wide.png&quot; 
                  Stretch=&quot;None&quot; />
    </controls:Panorama.Background>
    
    <controls:PanoramaItem Header=&quot;Item&quot;>

The same trick I used for the wallpapers, switching to accommodate for the dark or light theme could be used here too.