Showing posts with label wp8. Show all posts
Showing posts with label wp8. Show all posts

Tuesday, 2 April 2013

Smooth scrolling content on Windows Phone

     Gotta say that I am not 100% satisfied about the title of this blog post, but since I haven't found a better one I will use this one (don't get it wrong windows phone has smooth scrolling implemented). This post is focusing on how to smooth scroll the content of a ScrollViewer. If you are using the ScrollViewer you know that it already has the method ScrollToVerticalOffset that can be used to manually scroll the content but this method doesn't have any animation implemented so you will see only a fast redraw of the new content without getting the "feeling" that the content scrolled to the new position. The easiest way to achieve this task would be using a StoryBoard with an Animation on the property VerticalOffset of the ScrollViewer, but VerticalOffset is a read-only property so it cannot be set and therefore cannot be used for animation.
     The solution I found was to build a custom control and add a custom property that can be used as a target for a DoubleAnimation. The attached sample (see the link at the end of the post) is using a ListBox as the content of my Custom Control but you can use anything else inside the control (a better approach for the ListBox would be to create a custom control derived directly from ListBox and use the built-in ScrollViewer). 
      Let's start from the XAML part of the User Control:

  <ScrollViewer x:Name="scroller">  
<ContentPresenter Content="{Binding ContentArea, ElementName=userControl}"/>
</ScrollViewer>

    So we have a ScrollViewer which inside has a ContentPreseter that has its content binded to the control's property ContentArea. Now let us have a look at the .cs code.

 public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register("VerticalOffset",  
typeof(double), typeof(SmoothScroller), new PropertyMetadata(VerticalOffsetPropertyChanged));
public double VerticalOffset
{
get { return (double)this.GetValue(VerticalOffsetProperty); }
set { this.SetValue(VerticalOffsetProperty, value); }
}
private static void VerticalOffsetPropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
{
SmoothScroller cThis = sender as SmoothScroller;
cThis.scroller.ScrollToVerticalOffset((double)args.NewValue);
}
public static readonly DependencyProperty ContentAreaProperty = DependencyProperty.Register("ContentArea", typeof(object), typeof(SmoothScroller), null);
public object ContentArea
{
get { return (object)GetValue(ContentAreaProperty); }
set { SetValue(ContentAreaProperty, value); }
}

     The property that we will use for animation is the VerticalOffset that uses the method VerticalOffsetPropertyChanged to scroll to a vertical offset inside the control's scroller. The property VerticalOffset can be animated and we will use it to smooth scroll the ListBox content.
     Here is the content of the MainPage.xaml

  <uc:SmoothScroller x:Name="smoothScroller">  
<uc:SmoothScroller.ContentArea>
<ListBox x:Name="lstItems" ItemsSource="{Binding Items}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemTemplate="{StaticResource DataTemplate}" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</uc:SmoothScroller.ContentArea>
</uc:SmoothScroller>

     So we have the SmoothScroller control which inside its ContentArea has a ListBox (the ListBox has it's scrollviewer disabled). What the sample does is it is changing the selected item every second (incrementing the selectedindex) and scrolls the content so that the newly SelectedItem is centered in the ScrollViewer. Here is the code used for scrolling:

  void dt_Tick(object sender, EventArgs e)  
{
((ListBox)smoothScroller.ContentArea).SelectedIndex = idx;
var container = ((ListBox)smoothScroller.ContentArea).ItemContainerGenerator.ContainerFromIndex(idx) as FrameworkElement;
var transform = container.TransformToVisual(smoothScroller.scroller);
var elementLocation = transform.Transform(new Point(0, 0));
double newVerticalOffset = elementLocation.Y + smoothScroller.scroller.VerticalOffset - smoothScroller.scroller.ActualHeight / 2 ;
//Animate transition
DoubleAnimation verticalAnimation = new DoubleAnimation();
verticalAnimation.From = smoothScroller.scroller.VerticalOffset;
verticalAnimation.To = newVerticalOffset;
verticalAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
var sb = new Storyboard();
sb.Children.Add(verticalAnimation);
Storyboard.SetTarget(verticalAnimation, smoothScroller);
Storyboard.SetTargetProperty(verticalAnimation, new PropertyPath(SmoothScroller.VerticalOffsetProperty));
sb.Begin();
idx++;
if (idx >= 56)
dt.Stop();
}

     Pretty basic: select the new index in the ListBox, calculate the new VerticalOffset so that the newly selected item is centered in our scrollviewer and create and start a 500ms animation for the SmoothScroller.VerticalOffsetProperty. Anyway I am sure that you will better understand how it works when you will try the sample code.
     The sample is far from perfect (before starting a new animation I should check if the old one finished, should not automatically scroll when the user is manipulating the list,...).
     Here is a screenshot from the sample:

As usual let me know if you need help. The code works on both Windows Phone 7.1 and Windows Phone 8 SDK.

SOURCE CODE


Thursday, 7 March 2013

Easily localize your Windows Phone applications using the Multilingual App Toolkit

  Great news for Windows Phone developers. Today Microsoft released an updated version of its Multilingual App Toolkit for Visual Studio 2012 that supports also Windows Phone projects (the previous version only supported Windows Store projects). You can download the Visual Studio Extension from HERE. The extension itself is multilingual:
   So why is this extension so great in my opinion? As you probably know Windows Phone projects in Visual Studio already support multilingual localization for the applications based on .resw files. The Multilingual App Toolkit adds support for localization industry-standard XLIFF file format and also connects with the Microsoft Translator for quick translation suggestions.
  Lets have a quick looks on how it works. After you have installed the extension you will find a new menu entry inside the Visual Studio 2012 Tools menu with which you can enable or disable the Multilingual App Toolkit for your Windows Phone project.

 Once you have enabled the Multilingual App Toolkit Visual Studio added the XLIFF support and also generates the AppResources.qps-ploc.xlf which is the pseudo-language engine that helps identify translation issues during development. 
   From this moment you will USE ONLY the AppResources.resx file to add new resource strings and the extension (at compilation) will add the missing strings to the corresponding .xlf file. 
    To add new languages to your application you will only have to select the desired language as supported in the project Properties inside the Application section. Once a language is selected the extension automatically generates the corresponding Xlf file.

    You can then double click on the xlf file and Visual Studio will open the Multilingual Editor that enablesyou to edit the translation. If you add new strings to your AppResources.resx file remember to compile the project before opening the .xlf file or you will not see the newly added strings.

  Now with these 3-4 easy simple steps we have localized our application. You can use the the Microsoft Translator in order to have some suggestions but you should always double-check the translation in order to avoid strange translations and situations ("My Application" in italian is translated as "La mia domanda" which actually means My question).


  If you are building a test application remember to add the binding to the resource strings inside your .xaml and .cs files ({Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}" Style="{StaticResource PhoneTextNormalStyle} for Xaml or AppResources.value for .cs  )
 Some words about the AppResources.qps-ploc.xlf pseudo language file. Pseudo Language is an artificial modification of the software product intended to simulate real language localization. The pseudo language can be used to detect potential localizability issues or bugs early in the project cycle, before the actual localization starts. For more details about localizability testing with Pseudo Language see Localizability Testing. Inside Visual Studio if you right click on the Pseudo Language file you can select the Generate pseudo translations. 

In order to test it you will have to set the qps-ploc culture for the Application UI. Just add these 3 lines to your Application constructor (but remember to take them out when you don't need them anymore):

  public App()  
{
var ci = new System.Globalization.CultureInfo("qps-ploc");
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;


 More details on how to use the Multilingual App Toolkit can be found HERE.

 It is really great that Microsoft is migrating the localization of the apps to an open standard. I will get back to this subject with a post on how to share the same xlf files between windows phone and windows 8 projects)

NAMASTE

Wednesday, 2 January 2013

Saving the Windows Phone 8 Emulator State

    Saving the emulator state between runs was one of the feature needed for the Windows Phone emulator, but till now it is not officially supported. It even makes more sense now when the Windows Phone 8 emulator is a full working operating system and not a trimmed one like Windows Phone 7/7.5 was. You could configure an email account, personalize the start screen, install some applications, install certificates or even save the state of an application that requires a lot of data to synchronize before the actual debugging and have everything ready the next time you start the emulator.
   Today I was trying to run the Windows Phone 8 emulator on a Parallels 8 machine using this post because I hate Windows 8 performance in Bootcamp (the disk access is crappy and the UEFI mode still needs drivers for sound, video and a way to enable Hyper-V). I observed that the first time you run an Windows Phone emulator it took more than 40 seconds to start. The reason is that the SDK creates a new Virtual Machine in Hyper-V and saves a "clean" snapshot of it.

       On every subsequent run of that emulator the XDE automatically starts the virtual machine and immediately applies the snapshot (or starts the virtual machine from the snapshot directly). What caught my attention was the name of the snapshot for each virtual machine: 
  1. Emulator 720P - snapshot.720x1280.1024
  2. Emulator WVGA 512MB - snapshot.480x800.512
  3. Emulator WVGA - snapshot.480x800.1024
  4. Emulator WXGA - snapshot.768x1280.1024
     I tried and messed up the names and observed that XDE, if it doesn't see a certain Snapshot, it starts the Virtual Machine and creates a new snapshot with the required name. So in order to save the state it would be enough to alter/change the snapshot XDE uses to start the virtual machine. 
      First we need to start the emulator we want to personalize (in this post i will mess up the 512 WVGA emulator). This can be done in two ways:
  1. From Visual Studio by running a program on that emulator or from Application Deployment (the emulator is easy to personalize because you can zoom the content and you have the hardware buttons but will require a subsequent reset of the Virtual Machine from Hyper-V) 
  2. From Hyper-V manager by starting the Emulator WVGA 512MB virtual machine and applying the saved snapshot for a fast start. After the machine starts you will have to connect to it:

    Once connected to the emulator/virtual machine you can personalize/modify the way you want it to be. If you connected using Hyper-V these keyboard shortcuts will prove helpful (they also work in the emulator):


  • F1 - the same as pressing the back button
  • F2 – the same as pressing the home button
  • PageUp  - enables physical keyboard and minimizes the software keyboard
  • PageDown – disables physical keyboard and maximizes the software keyboard
  • F9 - volume up
  • F10 - volume down
  • F7 – invoke camera
  • F3 – invoke Bing search
If you want/need to install some xap's you can use Application Deployment with the Emulator. 
When you've reached the desired state go to the Hyper-V manager, select the Virtual machine that you are personalizing and hit Snapshot. This will create a new Snapshot(save state for the emulator).

If you've started the emulator from Visual Studio or Application Deployment App before you create the snapshot you will have to connect to the Virtual Machine from Hyper-V and from the menu Action select Reset (this will clean the ports used for debugging and the state you will save will be usable for Visual Studio and XDE).

After saving the new state the only thing you have to do is to rename the snapshot with the same name of the parent snapshot and delete the parent by right-clicking on it and select Delete Snapshot (DO NOT select Delete Snapshot Subtree).

You are now ready to go:  Turn Off the virtual machine from Hyper-V and try it from Visual Studio. Everything should work. If it doesn't it means that the state has some ports that Visual Studio uses still opened and in this case you will have to connect to the Virtual Machine from Hyper-V, Reset the machine from Action and save a new Snapshot.


My personalized emulator looks like this:


If you want to get back to an "unaltered" state just delete the snapshot of the corresponding Virtual Machine from Hyper-V Manager.


Hope saving the emulator state will help you in some scenarios.

NAMASTE!

Tuesday, 1 January 2013

GetNativeSystemInfo on Windows Phone 8

  This post is related/continues my previous one. I have written a small sample that shows how to call the GetNativeSystemInfo and IsProcessorFeaturePresent functions on Windows Phone 8 devices using a  C++ runtime component. For the moment I cannot think of a really good use for calling these functions because there are only two processors on the devices currently available. You could detect which of the two processors the device has and also its features. 
    Here is a screenshot of the sample running on my Nokia Lumia 920:



As it is the first day of the new year I Wish you all a great 2013!

SOURCE CODE

Wednesday, 26 December 2012

C# XAudio2 Sound Playback for Windows Phone

     Let's begin with a small introduction to XAudio2:
     XAudio2 is a low-level audio API. It provides a signal processing and mixing foundation for games that is similar to its predecessors, DirectSound and XAudio. XAudio2 is the replacement for both DirectSound and XAudio.
     XAudio2 abstracts audio generation by separating sound data from "voice", allowing each voice to be filtered by programmable digital signal processing and effects processing functions. Voices can be "submixed" together into a single stream. There is always only one Mastering Voice that outputs the result using WASAPI.

     XAudio2 is primarily intended for developing high performance audio engines for games. For game developers who want to add sound effects and background music to their modern games, XAudio2 offers an audio graph and mixing engine with low-latency and support for dynamic buffers, synchronous sample-accurate playback, and implicit source rate conversion. Compared to WASAPI, XAudio2 requires only a minimum amount of code even for complex audio solutions. Compared to the Media Foundation engine, XAudio2 is a low-level, low-latency C++ API that is designed for use in games.
     XAudio2 cannot be used for background music - for this task you will have to use the IMFMediaEngine. XAudio2 cannot be used for capturing audio - for this task you will have to use WASAPI. Do not use XAudio2 for media playback. For that task you can use MediaElement
    XAudio2 is part of the DirectX api that is included in the new Windows Phone 8 SDK. The Api is shared between Windows 8 and Windows Phone 8 which means that you will be able to fully reuse your source code on both platforms. 

If you want to use XAudio2 for your C#/VB/HTML code you have two options:
1. Use SharpDX . SharpDX is a wrapper of the DirectX Api under .Net platform. Theoretically you can use it to call XAudio2 api directly from your managed code. Practically what happens is that the .Net CLR/GC on ARM seem to block native threads so your audio will shutter/glitch in certain conditions. I had the same problem when I was developing our Windows 8 game Kids' Orchestra and the audio had glitches even on a core i7 processor.
2. The other option, which from my experience works better, is to develop an Windows Phone Runtime Component that will manage the XAudio2 part and expose the needed methods/events to the managed code.

      To better understand how it is done I took the Windows 8 sample XAudio2 audio file playback sample C++ from MSDN and ported to Windows Phone 8 by splitting it in two projects: The C#/Xaml part for the UI and the "audio" project which is a Windows Phone Runtime component developed in C++.
     The porting was pretty easy. I only had to re-code the player class to make it "visible" to the managed code project and added an event that will tell you when a certain Source Voice has finished playing its buffer/sound (we have 7 sounds and each sound has a Source Voice associated to it). If you need further details on how to write a Windows Phone Runtime component in C++ have a look at this  MSDN Post

    This sample only plays Wav files that are resources in the C++ project. You could also dynamically generate sounds in managed code and pass the Wave/buffer data as a byte[] to the runtime component. Inside the native code you will then generate an XAUDIO2_BUFFER and submit it to a Source Voice for playing.

     I have attached the SOURCE CODE for the Windows Phone project. If you have problems with it don't hesitate to contact me.

NAMASTE!

Thursday, 29 November 2012

Bluetooth Service's UUIDs

If you are developing on Windows Phone 8 and trying to communicate with a Bluetooth device using a StreamSocket these UUID's might come in handy:


ServiceDiscoveryServerServiceClassID= '{00001000-0000-1000-8000-00805F9B34FB}';
BrowseGroupDescriptorServiceClassID = '{00001001-0000-1000-8000-00805F9B34FB}';
PublicBrowseGroupServiceClass = '{00001002-0000-1000-8000-00805F9B34FB}';
SerialPortServiceClass = '{00001101-0000-1000-8000-00805F9B34FB}';
LANAccessUsingPPPServiceClass = '{00001102-0000-1000-8000-00805F9B34FB}';
DialupNetworkingServiceClas = '{00001103-0000-1000-8000-00805F9B34FB}';
IrMCSyncServiceClass = '{00001104-0000-1000-8000-00805F9B34FB}';
OBEXObjectPushServiceClass= '{00001105-0000-1000-8000-00805F9B34FB}';
OBEXFileTransferServiceClass = '{00001106-0000-1000-8000-00805F9B34FB}';
IrMCSyncCommandServiceClass= '{00001107-0000-1000-8000-00805F9B34FB}';
HeadsetServiceClass = '{00001108-0000-1000-8000-00805F9B34FB}';
CordlessTelephonyServiceClass = '{00001109-0000-1000-8000-00805F9B34FB}';
AudioSourceServiceClass = '{0000110A-0000-1000-8000-00805F9B34FB}';
AudioSinkServiceClass= '{0000110B-0000-1000-8000-00805F9B34FB}';
AVRemoteControlTargetServiceClass = '{0000110C-0000-1000-8000-00805F9B34FB}';
AdvancedAudioDistributionServiceClass = '{0000110D-0000-1000-8000-00805F9B34FB}';
AVRemoteControlServiceClass= '{0000110E-0000-1000-8000-00805F9B34FB}';
VideoConferencingServiceClass = '{0000110F-0000-1000-8000-00805F9B34FB}';
IntercomServiceClass = '{00001110-0000-1000-8000-00805F9B34FB}';
FaxServiceClass = '{00001111-0000-1000-8000-00805F9B34FB}';
HeadsetAudioGatewayServiceClass= '{00001112-0000-1000-8000-00805F9B34FB}';  
WAPServiceClass = '{00001113-0000-1000-8000-00805F9B34FB}';
WAPClientServiceClass = '{00001114-0000-1000-8000-00805F9B34FB}';
PANUServiceClass = '{00001115-0000-1000-8000-00805F9B34FB}';
NAPServiceClass = '{00001116-0000-1000-8000-00805F9B34FB}';
GNServiceClass = '{00001117-0000-1000-8000-00805F9B34FB}';
DirectPrintingServiceClass = '{00001118-0000-1000-8000-00805F9B34FB}';
ReferencePrintingServiceClass = '{00001119-0000-1000-8000-00805F9B34FB}';
ImagingServiceClass= '{0000111A-0000-1000-8000-00805F9B34FB}';
ImagingResponderServiceClass = '{0000111B-0000-1000-8000-00805F9B34FB}';
ImagingAutomaticArchiveServiceClass = '{0000111C-0000-1000-8000-00805F9B34FB}';
ImagingReferenceObjectsServiceClass = '{0000111D-0000-1000-8000-00805F9B34FB}';
HandsfreeServiceClass = '{0000111E-0000-1000-8000-00805F9B34FB}';
HandsfreeAudioGatewayServiceClass = '{0000111F-0000-1000-8000-00805F9B34FB}';
DirectPrintingReferenceObjectsServiceClass = '{00001120-0000-1000-8000-00805F9B34FB}';
ReflectedUIServiceClass = '{00001121-0000-1000-8000-00805F9B34FB}';
BasicPringingServiceClass = '{00001122-0000-1000-8000-00805F9B34FB}';
PrintingStatusServiceClass= '{00001123-0000-1000-8000-00805F9B34FB}';
HumanInterfaceDeviceServiceClass = '{00001124-0000-1000-8000-00805F9B34FB}';
HardcopyCableReplacementServiceClass = '{00001125-0000-1000-8000-00805F9B34FB}';
HCRPrintServiceClas = '{00001126-0000-1000-8000-00805F9B34FB}';
HCRScanServiceClass= '{00001127-0000-1000-8000-00805F9B34FB}';
CommonISDNAccessServiceClass = '{00001128-0000-1000-8000-00805F9B34FB}';
VideoConferencingGWServiceClass = '{00001129-0000-1000-8000-00805F9B34FB}';
UDIMTServiceClass = '{0000112A-0000-1000-8000-00805F9B34FB}';
UDITAServiceClass = '{0000112B-0000-1000-8000-00805F9B34FB}';
AudioVideoServiceClass = '{0000112C-0000-1000-8000-00805F9B34FB}';
SIMAccessServiceClass = '{0000112D-0000-1000-8000-00805F9B34FB}';
PnPInformationServiceClass= '{00001200-0000-1000-8000-00805F9B34FB}';
GenericNetworkingServiceClass = '{00001201-0000-1000-8000-00805F9B34FB}';
GenericFileTransferServiceClass = '{00001202-0000-1000-8000-00805F9B34FB}';
GenericAudioServiceClass= '{00001203-0000-1000-8000-00805F9B34FB}';
GenericTelephonyServiceClass = '{00001204-0000-1000-8000-00805F9B34FB}';



Friday, 31 August 2012

Windows Phone 8 inside VMWare

    More than a month ago some Microsoft guy in Asia made a terrible mistake and the LKG25 of Windows Phone 8 SDK leaked to the web. As I am not one of the lucky people that are the development program (as Mary Jo Foley suspected in a tweet and I believe it is true) I was more than happy when I got my hands onto the leaked version. At start I wanted to start blogging about the news that Windows Phone 8 will bring, but then I decided that it wouldn't be fair so I will wait until the official SDK. This post is not intended as a spoiler of any feature from WP8, but more like a proof of concept.
    I am sure many of you read on twitter that the new emulator is a virtual x86 machine and it comes with the virtual hard drive (.vhd file) divided on the screen resolutions.
    The idea came to me today while I was installing a clean virtual machine for development. Till now developing in a virtual machine for Windows Phone and debugging on the emulator with a decent speed/quality was impossible as you would have a virtual machines inside a virtual machine that degrades the performance exponentially. So what if you could have the development environment inside a virtual machine and then the emulator on another virtual machine that runs side by side and communicate on TCP/IP. In this case the performance of the emulator would be good (as it is not a vm inside a vm) and also the speed of the development environment would be acceptable. The virtual machine for the emulator would need 512MB or a maximum of 1GB.
     So the first thing I did is to install a trial version of VMWare Workstation 9 (should work with VMWare Fusion and also Parallels/VirtualBox). Then I have used WinIMAGE to convert the Flash.vhd file to Flash.vmdk which is the format that VMWare uses and created a virtual machine where I've attached the newly created vmdk.


     The good news is that the virtual machine works in VMWare right from the start. Not everything works (more decent is to say that some things work :) ) but hey it runs and I did nothing. The networking is not working but the most annoying part is the mouse pointer which is invisible in the virtual machine so I am blind pressing the mouse and at some point I am able to hit some buttons as you can see in the video :



More important than what this video shows (which is almost nothing) is what it could mean (even if I doubt we will see any of these in the near feature)


  • Theoretically developing for Windows Phone 8 on Windows 7 should be possible and not so hard to achieve (the partition where I installed Vmware Workstation runs Windows 7)

  • With some collaboration between Microsoft and VMWare/Parallels it would be possible to develop on a virtual machine and debug/deploy on the emulator which is another virtual machine. This would be great for Mac users but also for everyone (I might say like me) that likes to keep his development environments clean and separated from each other (I have a VM with VS2008 and Compact Framework, soon VS2010 will pass in a virtual machine too, I don't want to install VS2010 on my Windows 8 partition etc.)


  • The emulator is an x86 virtual machine so it shouldn't be so hard to achieve plug-gable hardware into the emulator (like connect the webcam to the emulator camera, storage card to an USB key or shared folder, NFC hardware - here I might be mistaking but should be a serial connection after all). It would give us a better development environment.

P.S. Seeing that it is a virtual machine I beg the team which is in charge of the emulator to SAVE the emulator/virtual machine state between resets. It is really annoying to always start from 0 and none of the other major mobile platforms has this limitation.


Till next time NAMASTE to you my reader.