Windows 10: One Platform for All Devices
Windows 10 is now closer than ever to supporting Microsoft's vision of one platform for all devices. Windows 10 runs on Raspberry Pis, Xbox Ones, desktops, tablets, phones, and even HoloLens. Although users typically expect things to "just work" on each of these devices, as developers it's difficult to imagine how to support all of these different devices using one code base. After attending the Build 2015 conference I've been able to discover how to actually make that happen. Supporting all of these devices in Universal Windows Platform (UWP) 10 applications can be thought of in two different ways: Providing unique functionality to devices and providing an appropriate user interface (UI) and user experience (UX) to devices. In this blog post I will go over both of those items and explain how you can support various devices in your UWP application.
Unique Functionality for Devices
Phones have accelerometers and cellular radios, Xboxes have Kinect, HoloLens has Holograms, and many other devices have their own unique features that make them work. Supporting all of these peripherals and hardware can be difficult, but Microsoft has done a good job of abstracting the logic for developers.
The first hurdle to support these different devices is input. Although in Windows 10 it's fairly easy to use a keyboard and mouse on an Xbox and phone, in most cases it's a better experience to use the typical input methods for devices to interact with applications. In Windows 10 Microsoft has made all of these different devices work as best as possible for input. Navigating apps with an Xbox controller, touch, mouse, keyboard, etc. is handled as best as possible by the operating system out-of-the-box. Although developers may want to optimize their applications in certain ways for these different input methods, having them work natively saves a huge amount of coding and provides users with a more consistent experience for all applications.
Another hurdle to consider with different devices is supporting different optional hardware. As mentioned above different device families, such as phones, have different hardware, such as cellular radios. Applications that do not need to utilize functionality specific to this optional hardware will not need to do anything extra. Applications that do want to utilize functionality from the optional hardware, such as sending an SMS message, will need to do some additional work to support it.
Microsoft has provided libraries for all of the different device families (Xbox and HoloLens still to come). When you want to access functionality that may only be available for a certain device family, you can simply add a reference to that specific library, such as the UWP Mobile library, within your application. In addition to adding the reference, it is also recommended that you provide the appropriate checks to make sure the functionality is available on the device that the application is being run on. You should not ever assume, for example, that a device with a small screen is a phone and therefore has a cellular radio. Check that the functionality exists whenever it is being used. I would also recommend that you adjust your UI to ensure that only available functionality is shown to the user.
Unique UI/UX for Devices
While supporting the wide range of devices an application must support an equally large range of screen sizes. Developers familiar with "responsive" design in web applications are already aware how big of an issue this can be. In Windows 10 Microsoft has provided some new tools that help developers adapt their applications to everything from a low DPI phone to a large 4k television.
Before going into details about how to react to different screen sizes it is important to understand effective pixels (EPI). An effective pixel is a unit of measurement that Microsoft has defined to help standardize measurements of controls in XAML across devices. This value is calculated by considering a screen's pixel density, size, resolution, and expected viewing distance. The expected viewing distance, I assume, is calculated by the screen size - consider the fact that you typically view your phone close to your face and a TV much farther from your face. In the diagram below you can see how the effective pixels of screens vary across different screen sizes.
Using EPIs within UWP apps allows the operating system to automatically scale controls and assets as needed for different screens.
Although EPI helps scale controls and assets, it is still recommended to provide different scales of assets to help prevent artifacting. One interesting comment made during Build 2015 was regarding how they are handling asset scaling. During download they will download only the images that are scaled appropriately for the device on which you are downloading the application. If you later add additional monitors in some way and need a new scale for images then it will flag that in your application and download those new scales when your application is updated. If you don't use a particular scale for over 30 days then it will discard those scales assuming that you do not need them anymore.
Although there are certainly hacks that can be used in existing Windows 8.1 applications to adjust an application's UI for different screen sizes, Microsoft has provided new adaptive triggers to make it much easier. These are triggers defined in the view state managers for components which use rules to determine how to manipulate objects. To better understand this, you can consider the existing visual states on many XAML controls. Within the visual state manager you have been able to use the different states to trigger manipulations of the controls:
Similarly in Windows 10 you can use the new adaptive triggers to define rules to which you can listen and react:
Although you are able to create new triggers, the MinWindowWidth trigger shown above is the most applicable trigger to listen for when updating the UI for different screen sizes.
Now that you can listen and react to changes in the screen size it is important to know how to react. Obviously there will be some UI components that just won't work for different screens which you can update appropriately, but it's important to know that UX patterns can and, in most cases, should change for different screen sizes. Users expect an easy one-handed experience on a phone (small screen) but a keyboard and mouse experience on a desktop (larger screen). Microsoft has provided a new layout control to help with many common scenarios for adjusting to different screen sizes: the RelativeLayout control. This control allows laying out children relative to each other. Using this control you are able to easily implement common scenarios such as changing a two or three column layout on larger screens to a one column stacked layout on smaller screens. A WrapGrid is an existing control that also provides an easy way to update your application's layout for various screen sizes. More information regarding the various design recommendations for UWP apps across various screen sizes can be found at http://design.windows.com.
Overall I believe Microsoft has provided some good tooling to support the various devices that will run Windows 10. If you are interested in viewing some specific examples of UWP applications handling these scenarios you can find sample applications on GitHub.