Wrap Lottie in UWP Apps

NOTE: This is an example on how to achieve showing Lottie examples in a webview. In the future I will make a library with animation methods, loading, configuration, etc.

lottietransparent

What is all about?

The design of apps in Windows 10 it’s a bit Dark and Light world. At the beginning since Windows Phone 7 it was about performance and lack of resources and templates. All my icons were solid white in that age.

These days we can start using multicolor svg icons and also animations. The typical animations are about changing the opacity, position, scale, color but never the shape of an Element. In part is because it is not an easy work to do but there is an After Effects plugin+library that is the source of all this movement: Bodymovin

When I started to see flat animations vector based in several websites and after reading that were based on Bodymovin appeared to me Lottie which is a native version of this javascript library it get me a bet out of the game. The reason is because XAML is powerful but is not complete, it does not have the power to change shapes, grow lines, etc.

Testing Lottie files in Bodymovin

Lottie is only for Android and IOS, so in order to make it work in UWP the only way is make it work in a webview using Bodymovin, so first let’s get files.

There is a new website LottieFiles (I get to that with the issue Path animations from Tamás Deme)  containing the json animation files ready to work with Lottie. The first question here is are compatible, hopefully yes, at least the files I’ve tested.

Lottie Transparency

Now we have a file, for instance lottie logo json, I had to understand the logic of that file to make it transparent, first I make an screenshot and the color was RGB (0,209,193) after several trials I discovered the colors are written from 0 to 1, so 209/256 it is about 0.82 in this case the background is

{
  "ty": "fl",
  "fillEnabled": true,
  "c": { "k": [ 0, 0.82, 0.76, 1 ] },
  "o": { "k": 1 },
  "nm": "Fill 1"
},

Now to make it transparent I set the “0”: { “k” : 1 } to 0, easy to find, isn’t it?.

Html transparency and scrollbars

By default the Webview control make appear a vertical scrollbar and it is not transparent, to solve all that

<html style="width: 100%;height: 100%;overflow: hidden;">
...
<body style="background-color:transparent; margin: 0px;height: 100%;overflow: hidden;">

Take care of that, it might be useful for many situations.

The library

How do we place the Bodymovin library running on a UWP from the file. Well after several trials, I found you have to use ms-appx.web, but it was not working, so I was looking for a way to debug that. You can do that with the following:

debugscript

If you set the debugger to Script, you can debug the Webview until you find the correct path, in this case:

 <script src="ms-appx-web:///Data/bodymovin.js"></script>

Where the file is content and copy always. with all of that adjustments, the code will look like:

<!DOCTYPE html>
<html style="width: 100%;height: 100%;overflow: hidden;">
<head>
    <script src="ms-appx-web:///Data/bodymovin.js"></script>
</head>
<body style="background-color:transparent; margin: 0px;height: 100%;overflow: hidden;">
<div style="width:100%;height:100%;background-color:transparent" id="bodymovin"></div>
<script>
        var animData = { container: document.getElementById('bodymovin'), renderer: 'svg', loop: true, autoplay: true, animationData: animationdata };
        var anim = bodymovin.loadAnimation(animData);
    </script>
</body>
</html>

In next versions, I will make the code with configuration about when to start, looping, etc.

 The Webview

This part is piece of cake, what I did is replace the parameter in ‘animdata’ with the json. In theory is possible to read as src, but at the moment cannot make it work.

private async void InitializeLottie()
{
    var html = await BMManager.GetTemplate();
    var jsonuri = "ms-appx:///Data/lottie_logo_1.json";
    var data = await BMManager.ReadData(jsonuri);
    html = html.Replace("animationdata", data);
    WebView web = new WebView { DefaultBackgroundColor = Colors.Transparent };
    LayoutRoot.Children.Add(web);
    await Task.Delay(1000);
    web.NavigateToString(html);
}

With that after loading the page you will have the cool animation on your app!.

So here is a base to add svg animations into a UWP app.

Next Steps

There are plenty of steps to do from here, testing more jsons, making Composition animations with the webview to view how it behaves (pixilation, flickering). Making a complete library with animation control, etc.

Source code

You can download and try the example:  github-mark-64px

In my case, I’m using Windows 10, 15031. If it works also in your mobile, please share if it works, thank you @juanpaexpedite

If you find it useful, help me to continue, Tips welcome, it really helps!

Advertisements

Paint 3D Dialog Box using Composition Shadow

paint3d.JPG

After analyzing the Dialog Box from Paint 3D (DBP3), I decided to create one by myself. I think the DBP3 should use:

  1. The Content Dialog class instead of a custom one and trying to disable elements. It has appear and disappear transitions so it works pretty well.
  2. The Composition shadow instead 7 borders around the control.

The first thing we have to do is customize the parameters of the content dialog. To do that, you can find the file or just use UWP Technical guide:

(If you find the App useful consider about tapping the  menu – smile – remove ads, it really helps.)

contentdialogstyle.JPG

With that you know what are the properties to change and ThemeResources to replace its values.

Styles

So now in the App.xaml:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Dark">
                <SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush">#3111</SolidColorBrush>
                <Thickness x:Key="ContentDialogContentScrollViewerMargin">0</Thickness>
                <Thickness x:Key="ContentDialogPadding">0</Thickness>
            </ResourceDictionary>
            <ResourceDictionary x:Key="Light">
                <SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Opacity="0.5">3EEE</SolidColorBrush>
                <Thickness x:Key="ContentDialogContentScrollViewerMargin">0</Thickness>
                <Thickness x:Key="ContentDialogPadding">0</Thickness>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Application.Resources>

Now in the Page we are, or here in App.xaml if you prefer, add the following style to override all paddings and margins:

<Page.Resources>
<Style TargetType="ContentDialog" x:Key="PaintDialogBoxStyle" x:Name="PaintDialogBoxStyle">
        <Setter Property="Padding" Value="12"/>
        <Setter Property="MaxHeight" Value="400" />
        <Setter Property="MinHeight" Value="0" />
        <Setter Property="MaxWidth" Value="500" />
        <Setter Property="MinWidth" Value="0" />
        <Setter Property="Padding" Value="0"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="FullSizeDesired" Value="False"/>
        <Setter Property="Background" Value="Transparent"/>
    </Style>

</Page.Resources>

The dialog

XAML

Let’s create a UserControl or a Templated Control with the following XAML structure:

<Grid Width="492" Height="340" Background="Transparent">
    <Canvas x:Name="ShadowHost" Margin="18" Background="Transparent"/>
    <Grid x:Name="LayoutRoot"  Margin="20"  Background="#FFF0F2F3">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
        <Border BorderThickness="1" BorderBrush="{ThemeResource ContentDialogBorderBrush}" Grid.RowSpan="3"/>
        <Image Source="ms-appx:///Assets/Images/Paint_Logo_with_Trademark_ABOUT_POPUP.png" Height="80" VerticalAlignment="Top" Margin="0,42,0,0"/>
            <StackPanel Grid.Row="1" Margin="0,12,0,0">
                <HyperlinkButton Foreground="#FF4D4D75" Content="Contoso Software License Terms" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
                <HyperlinkButton Foreground="#FF4D4D75" Content="Privacy Statement" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
                <HyperlinkButton Foreground="#FF4D4D75" Content="Contoso Services Agreement" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
                <TextBlock Foreground="#FF4D4D75" Text="1.1701.12017.0" FontSize="12" Padding="0" HorizontalAlignment="Center"/>
            </StackPanel>
            <Button Click="CloseDialog" Grid.Row="2" Margin="0,0,0,24" Width="200" Content="OK" HorizontalAlignment="Center"/>
        </Grid>
</Grid>

To explain the values:

  1. The original DBP3 has a size of 484×332 so to avoid adding many values I decided to set that size + 2×4 and the Margins 20 and 18 make the game to have the panel inside and the shadow outside.
  2. The rule of creating a Canvas for the host is based on the latest documentation from MSDN about The Visual Layer with XAML.
  3. To make easy the position of the button I decided to set it inside and avoid the buttons the DialogContent has.
  4. The rest is from the values the Visual Tree of Paint 3D.

Code

We have to make transparent the rectangle that appears when a Content Dialog is shown and when the button is Clicked make it disappear.

Note: Clicked is for (keyboard enter, mouse click and touch tap), and Tapped is for (tapped and click).

public sealed partial class AboutElement : UserControl
    {
        public AboutElement()
        {
            this.InitializeComponent();

            this.Loading += AboutElement_Loading;
            this.Loaded += AboutElement_Loaded;
        }

        private void AboutElement_Loading(FrameworkElement sender, object args)
        {
            var popup = VisualTreeHelper.GetOpenPopups(Window.Current).FirstOrDefault(p=> p.Child is Rectangle);

            if(popup?.Child is Rectangle rectangle)
            {
                rectangle.Fill = new SolidColorBrush(Colors.Transparent);
            }
        }

        private void AboutElement_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeDropShadow(ShadowHost);
        }

        private void InitializeDropShadow(UIElement shadowHost)
        {
            Visual hostVisual = ElementCompositionPreview.GetElementVisual(shadowHost);
            Compositor compositor = hostVisual.Compositor;

            // Create a drop shadow
            var dropShadow = compositor.CreateDropShadow();
            dropShadow.Color = Color.FromArgb(128, 0, 0, 0);
            dropShadow.BlurRadius = 10.0f;
            dropShadow.Offset = new Vector3(0.0f);

            var shadowVisual = compositor.CreateSpriteVisual();
            shadowVisual.Shadow = dropShadow;

            ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual);

            // Make sure size of shadow host and shadow visual always stay in sync
            var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
            bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);

            shadowVisual.StartAnimation("Size", bindSizeAnimation);
        }

        private void CloseDialog(object sender, RoutedEventArgs e)
        {
            var popup = VisualTreeHelper.GetOpenPopups(Window.Current).FirstOrDefault(p => p.Child is ContentDialog);

            if (popup?.Child is ContentDialog dialog)
            {
                dialog.Hide();
            }

        }
    }

Calling

And finally to call it from a view:

private async void ShowDialog()
{
    var dialog = new ContentDialog { Content = new AboutElement(), Style = PaintDialogBoxStyle};
    await dialog.ShowAsync();
}

So with the existing API and without inventing new panels and controls, you can create the Dialog using the standard methods and not experiments like I explained in previous posts.

I prefer setting the border to transparent like the following, but it’s just my opinion:

paint3dprefer

Hope you find it useful, get ready for Feb 8, let’s see what happens.

@juanpaexpedite

Experiments with Creators Update 15025

I am trying to find the Neon features. There are different ways that could make it work and apart I will make tests with some features to understand what are their purposes.

ApplicationView

Here we have new functionality like making the app like a Compact Overlay Window:

compact

When the window is out of focus even the title bar disappears and shows the Top left and Top Right Text Boxes, You can resize it from 150×150 up to might be 500 x 500. No idea the purpose, might be advanced interactive notifications.

Compact2.jpg

private async void PageLoaded(object sender, RoutedEventArgs e)
{
    this.SizeChanged += MainPage_SizeChanged;

    await Task.Delay(5000);
    var view = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView();
    await view.TryEnterViewModeAsync(ApplicationViewMode.CompactOverlay);
}

NotesWindowManagerPreview

Inside Application model we have:

var notes = Windows.ApplicationModel.Preview.Notes.NotesWindowManagerPreview.GetForCurrentApp();
var contract = new PreviewNotesContract();

Might be we can create some kind of notes, sticky notes? no idea. there are only int references and cannot make any advance on that. There are also inside the preview another one for InkWorkspace and Holographic.

HDMI information

var hdmiInfo = Windows.Graphics.Display.Core.HdmiDisplayInformation.GetForCurrentView();

It returns null, so no surprises. I understand this appeared because the Surface Studio and its HDMI color spaces management.

Unloading XAML

Another in progress

XamlMarkupHelper.UnloadObject(this.BRTextBlock);

It throws an exception, it might be for reading XAML and removing items, or to dispose items from a Panel, I do not know. no more methods, constructors, etc.

I prefer to no continue with this post because is a waste of time using this SDK.

 

 

 

 

 

 

Analyzing Paint 3D 2/2

The Paint 3D app has been updated, and they have solved the issue shown in the previous post Analyzing Paint 3D 1/2 , now if you press tab, it will only cycle around the control PaintDialog.

about.JPG

I have also taken a look to all the fonts in the system for Paint, Edge, and more fonts. At the moment all remain the same. You find them by searching *.ttf in Windows/SystemApps.

There are no news about using SVGImageSource instead Canvas Path for the tool icons. I understand will be changed in the CreatorsUpdate.

Before digging about the properties and structure of the controls, you can take a look to them with Visual Studio. Create a new project and add the references from the winmd files, then you will be able to open that:

metadata

It is only the information from the metatada, not the source code, so you won’t able to use that. But it is interesting because you can do it directly from VS.

Let’s analyze first the visuals left from the previous post and then the rest of the controls.

Shadows

In this release, we still have a rectangle with a lineargradientbrush for the shadows of the panels, they have the following properties:

shadow

If you do not usually apply linear gradient brushes, you can get more information at msdn uwp brushes.

Now you can apply the same shadow in your apps, let’s take a look to the controls that appear like a popup.

PaintDialog

It is a Content Control that simulates a popup dialog. It does not appear in the Canvas Panel of the Popups, it is inside the main visual tree and the controls have this inside to show its functionality limiting the actions inside it.

HsvColorPicker

hsv

This is a control that appears with a PaintDialog, it has a shadow, really complex because it has a Shadow Grid with 7 borders to make the shadow. It bothers my who decided and why to do that:

shadow2

The background brush of this control, is defined in the DropShadowBorder #FFF6F6F6, it is not an static resource, I cannot assure that, but apparently it is. The margin of the header is 24,28,0,0. So now are a factor x4. and the color of the title is Black with 0.6 of opacity.

The color selector is SaturationGradient.png inside Content folder that looks like the following:

gradient

And below contains the color which is binded to the color of other Control.

The slider to change the hue, has been customized with a gradient with 29 stops:

gradientinfo

I understand this gradient has been made with a tool, and not hardcoded. I would like to see more Win2D and Composition in this app but at the moment nothing really surprising.

After looking the rest of the information that can be extracted, and watching that the SwapChainPanel does not show any information when is used in 3D, I decided to give my conclusions and continue when the Creators Update and the new Universal Examples on GitHub get released.

Conclusions

There is no way to analyze styles, transitions, etc. from the Live Visual Tree. might be in the future will appear a third party tool to analyze it. (In case you know how please share)

I am waiting new real documentation ‘Acrylic’ with personas, XAML lights, shadows, SvgImageSource, updated Compiled binding and many more. Might be on Feb 8 we get more information.

The GitHub repositories are stopped, most of them have 6 months old and composition repo 4 months, that means ages.

Paint 3D app is not using any internal SDK it is using the typical we use. it is a really outdated version comparing it to the release I think we will see in a near future. Might be when release the new SDK without being prerelease.

And that’s all not surprises but details, as always @juanpaexpedite

UWP Protect files embedding them

When developing apps you search for practical, tested and for real environments information. That is always my purpose, improve and go beyond in universal apps.

Let’s begin reading files in universal apps.

It is just two lines to read a file in your app and assign to an string, but might you do not know that you can go inside the folder of that app, navigate to the Assets folder and grab that file.

An UWP app should be a safe sandbox in both ways, one for the user to feel safe its Windows and on the other side for the developer, keeping the files safe.

In theory there is no limit about the size of the file to protect, can be any you consider, because the reader is asynchronous it can last how long it takes.

Text File

Suppose you have a json with few data, you prefer use json because it’s fast. If you place it at Assets/Data and the build options to Content, it will be available for any user at that path like C:\Program Files\WindowsApps\[AppName]_[Version]_[Platform]__[Id]

Content file

When you want to read or delete a text file with the build action as Content:

public static async Task<string> LoadContentTextFileAsync(string contenturi)
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(contenturi));

    return await FileIO.ReadTextAsync(file);
}

public static async Task<bool> DeleteContentFile(string contenturi)
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(contenturi));

    if (file != null)
    {
        await file.DeleteAsync(StorageDeleteOption.PermanentDelete);
        return true;
    }
    return false;
}

Now let’s change it to Embedded resource, and of course do not copy the file:

embedderesource

Take care, that if you have debugged the app before, you must uninstall it to make  disappear the file from Assets/Data.

The following methods makes really easy change from content to embedded resource.

public static Stream LoadEmbeddedStreamAsync(Type type, string contenturi)
{
    var assembly = type.GetTypeInfo().Assembly;
    var relativepath = ConvertContentEmbedded(contenturi);
    var embeddedpath = $"{type.Namespace}.{relativepath}";

    var stream = assembly.GetManifestResourceStream(embeddedpath);

    return stream;
}

public static async Task<string> LoadEmbeddedTextFileAsync(Type type, string contenturi)
{
    var stream = LoadEmbeddedStreamAsync(type, contenturi);

    return await ReadStringFromStreamAsync(stream);
}

What really means setting the file as embedded resource?

For one side we have added another entry to the resources.pri file (in case the file is in the project, in case is in a library it will be called [libraryname].pri.

To take a look to the file, just get the XML with the following VS tool:

pridecoder2

And not just open it and find the entry of the file:

resourceentry.JPG

Aside: If you install a UWP SDK like the 15003 prerelease, this and other tools are unique, that means that you won’t be able to upload an appx, because this tool ‘makepri’ is not a released version, you will have to uninstall both SDKs, and install again the latest released one.

If I understand it right, the file is embedded in the executable, so in theory is really protected, taking a look to it, we see the change in the size:

executables

We can check that easily adding an Image and setting it like a embedded resource:

addedimage

It is clear where the file is embedded now. Now we understand we should not add big files in here because it will make increase the executable and decrease time loading and performance.

But what about adding it inside a UWP library?

Big Files

In this case, I am going to add an image inside a assets library and try to show in a Image Control.

To make things easier, create a class in the UWP library called Library and the project AssetsLibrary and also let’s add a file inside Images:

assetslibrary

Now set the image as embedded resource and call it from the code behind of a page:

private async void Initialize()
{
    var stream = ResourceFilesService.LoadEmbeddedStreamAsync(typeof(Library),"ms-appx:///Images/spacebackground.jpg");

    var bitmapimage = new BitmapImage();

    BackgroundImage.Source = bitmapimage;

    await bitmapimage.SetSourceAsync(stream.AsRandomAccessStream());
}

Perfect the image is shown in the BackgroundImage control. So now you can implement behaviors or static methods for compiled binding to set the images you want to protect.

Big files to the local folder

Finally in case you need to copy a file from an embedded resource to the local folder, follow these steps:

public static async Task CopyResourceToLocal(Type type, string resourcepath, string filename)
{
    var localFolder = ApplicationData.Current.LocalFolder;
    var dbFile = await localFolder.TryGetItemAsync(filename) as StorageFile;

    if (null == dbFile)
    {
        var stream = LoadEmbeddedStreamAsync(type, resourcepath);

        //Copy the stream
        var storageFile = await localFolder.CreateFileAsync(filename);

        using (var outputStream = await storageFile.OpenStreamForWriteAsync())
        {
            await stream.CopyToAsync(outputStream);
        }
    }
}

For instance

 await ResourceFilesService.CopyResourceToLocal(typeof(Library),"ms-appx:///Data/Resource.txt","Local.txt");

And that’s all hope with this information, you can keep your app more robust avoiding possible user mistakes.

Download the ResourcesFileManager.cs

Take a look all I create about #UWP #Windows10 at @juanpaexpedite

Analyzing Paint 3D 1/2

Until we have the new Windows 10 Creators Update and the new SDKs, APIs, etc. I need few days to relax my mind from creating my new Universal app Games Time Machine. I learn a lot about performance, SQLite with EF7 and UI new ways. I encourage you to grab it at Games Time Machine at the W10 Store and ask me about any part you are interested, I will glad to address on how to solve an issue or how to make it work any you need.

Now after following the twitter from @justinxinliu I decided to analyze Paint 3D, in theory the most next Creators Update App style.

Attaching

The first step is launch Paint 3D and now launch VS2017 (might be with 2015 works but you know is 2 years old now 🐱🐉 ), and attach in the following way:

first

Now search for Paint and attach in Native mode:

second

And here we go, now we can analyze several interesting parts of the app.

App Manifest

Just a quick view of what is interesting inside:

appx

As you can see there is a Device called Windows.Team (no idea what can be). and an internal SDK 14800.

From the Uri rules, look like the codename was Denali which is a protected website:

urirules

Layout

layout

The app contains:

  1. Grid with TopBar, SideBar, CommunityDiscoveryPanel, ContextSideBar, Grid, Rectangle, HamburgerMenu and a DebugMenu.
  2. A ContentControl binded to the StartViewModel.StartVM, might be a trigger to begin some kind of actions.
  3. The AboutBox, it is interesting because it’s full size, with a Brush Transparent (to lock all the elements behind). An small bug it has is that should block the key or the controls behind when the AboutBox is shown, but it’s not, you can press tab and cycle control focus and activate them. Hope in new releases they give an easier option to lock what is behind.paintfocus.JPG
  4. The HsvColorPicker, which I will analyze later.
  5. A Loading overlay, which must be like a MessageDialog (CancelCoomand, Description, Image, IsOpen, Title)
  6. A Change Text Overlay similar to the previous one, (CancelCommand, OkCommand, Text)
  7. A grid that contains the WebBlendControl, yes web. I will take a look to it later.

Top Bar

This bar if 50 Height, not 48, so is not now a x4 factor, the background color is #FF363941. I should try referencing an static resource to know if this value is hard coded or referenced.

topbar

It contains three parts, The hamburger, which is an ActionableCheckBox, a ResponsivePanel to change the ExpandedView and the CompressedView, and another Grid on the right for the Actions and Remix3D.

  1. The Hamburger ActionableCheckBox is 66×50 with minSize 66×50 and it comes from the style of Checkbox.it contains and IsAction Property to change if the Menu is Open or not.
  2. The Responsive Panel (in expanded view) [I do not know if it is possible to analyze the Visual States]. To summarize is like an ItemsPanel with ItemsSource and SelectedItem. The ItemContainerStyle sets the size to 66×50 of each item.
    1. Each item is a SimpleSelectorItem that changes the visibility of a grid when selected or unselected, the only difference is a linearbackgroundbrush I will detail later.
  3. And finally on the right a non named panel, a bit less organize with a 66×66 button, yes is bigger, why? and also the other buttons are 66×66.

Side Bar

sidebar

This bar contains a lot of controls inside, let’s analyze how are organize (hardcoded or with binding) and what kind of controls are. All inner panels are of type ResponsivePanel that changed from ExpandedView to CompressedView depending on the Window size.

It has two parts, the tool section, and the colors below. Let’s begin with the low part, the color selector, the container is a grid of 264W and inside it is an stack panel. The most interesting part is the colors section. It is a RelativePanel with a WrapPanel with all the Colors of type ColourThumb.

colorborder

It changes the Visibility of the Grid, the over has -2 of margin and 2 of Border Thickness to make the effect of grow.

Now let’s analyze the tools section. each tool item is a canvas with several paths inside, might be in the future we see SVG items here.

Interaction

In summary after digging in the visual tree, it’s a SwapChainPanel (HighFrecuencyInputPanel) , I will have to take a look if it’s the same like the InkCanvas.

Bottom Bar

This contains ZoomScale Buttons and buttons to change the view to edit or view.

Now we have analyzed the layout and itemsizes, let’s continue with the Icons used and fonts.

Icons & Fonts

One of the firsts parts I always take a look is the fonts and the symbols what are they done, pixel, paths, fonts, etc.

Let’s analyze the Top Bar:

The Hamburguer button is of type ActionableCheckBox, the content is an Icon with HamburgerIcon which is slightly different from the Seoe MDL2 Assets.

Now the middle top panel is of type PaintStudio..ResponsivePanel with popup values, Each button inside, is a PaintStudio..SimpleSelectorItem and the content is using this font Assets/Fonts/PaintA.ttf#paint and the chars are B, ~, and so on, so apparently are not a new Segoe Creators Update Font.

Let’s see if we can achieve that font. The app is installed in a place like:

C:\Program Files\WindowsApps\Microsoft.MSPaint_1.1612.14017.0_x64__8wekyb3d8bbwe

And here we can see inside the Assets Folder three fonts: Icons.ttf, BhaiMDL2.1.84.ttf and PaintA.ttf

Icons

This font contains the following information:

fontinfo

Generated by IcoMoon, interesting, isn’t it?. And it just contains 3 characters:

fontchars

Beihai MDL

This name looks like the Creators Update internal name, later I will explain why. This second one is from Microsoft and is an small subset from Segoe MDL2 Assets:

secondfont

As you can see in the screenshot, containing the whole collection, it contains a new facebook and twitter symbols which, I think are not in Segoe MDL2  Assets.

Paint

Now let’s take a look to the PaintA.ttf

paintfont

All the screenshots were using my app Universal Character Map . except the first one, using FontForge desktop app (great for editing fonts). As you can see here is where includes a Hamburger symbol. I do not understand why is not the same from Segoe, might be in the Creators Update all will be reorganized. Also all the icons included in the Hamburger menu were done using this font.

For the rest of the menu items, all are custom controls. Hope they are included by default or in templates to stylish new apps.

Colors & Gradients

All the menus, all the icons, etc. have the following gradient:

gradient

It looks like the colors do not belong to an Style (static resource) but might be included in the future for default styles in UWP apps.

In the following post, I will analyze the controls, all the coloring and shadows, and I will try to dig about visualstates and animations if it’s possible. Meanwhile the other laptop is to 15014, I will check if there is any new version of Paint3D or any other app to analyze.

Regards @juanpaexpedite

 

Compiled binding,Page Resources and Visual States

I have tried to find the cleanest way in terms of reusability, less code repeating, functionality, etc. And after plenty of experiments the following is the one I consider more interesting. First I explain how to use directly from the page, and after from a datatemplate.

Page Resources

When we define a double in XAML like a resource, you will be able to use as a resource just once, also you will able to change on runtime using the VisualStateTriggers, but the Controls referenced to it won’t get the updates, because we only have StaticResources in UWP and no DynamicResources. Also a x:Double cannot have a Name in the Page Resources Section.

Having this in mind, you can define tons of dependency properties in your XAML Page code behind and bind it but makes the code less clean. So what can we do, let’s create XAML Properties.

To begin let’s define the DoubleProperty which represents a double in the XAML world, that means a DependencyObject:

public class DoubleProperty : DependencyObject
    {
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(nameof(Value), typeof(double), typeof(DoubleProperty),
                new PropertyMetadata(DependencyProperty.UnsetValue));
    }

Now we can use it as a real resource because now can have a name in the Page Resources.

<Page.Resources>
        <c:DoubleProperty x:Name="HeaderFontSize" x:Key="HeaderFontSize" Value="24.0"/>
        <c:DoubleProperty x:Name="DescriptionFontSize" x:Key="DescriptionFontSize" Value="14.0"/>
</Page.Resources>

Compiled binding

Now in case we want to create a TextBlock with one of the defined font sizes:


<TextBlock Text="Sections"  FontSize="{x:Bind HeaderFontSize.Value, Mode=OneWay}" />

Visual States

And now let’s create the Visual States Section

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="VisualStates" >
        <VisualState x:Name="Full">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="600" />
            </VisualState.StateTriggers>
        </VisualState>
        <VisualState x:Name="Small">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="DescriptionFontSize.Value" Value="12"/>
                <Setter Target="HeaderFontSize.Value" Value="18"/>
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

Where we can easily change the values because this resources have x:Name. Now when you run the app you will see how it adapts the fontsize according to the Windows Width.

Now, the WOW part, at least IMHO, because there is not an official way to do it at the moment.

Data Templates

First we need to define a Current static property of the Page in the constructor, it is the only code behind you need:

public static HomeView Current { get; set; }
public HomeView()
{
    Current = this;
    this.InitializeComponent();
}

Now we can bind to it from a DataTemplate for instance:

<DataTemplate x:Key="SampleDataTemplate" x:DataType="m:SectionInfo">
   <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="240"/>
    </Grid.RowDefinitions>
    <TextBlock Text="{x:Bind Name, Mode=OneWay}" FontSize="{x:Bind local:HomeView.Current.HeaderFontSize.Value, Mode=OneWay}"  />
    <TextBlock Grid.Row="1" Text="{x:Bind Description, Mode=OneWay}" FontSize="{x:Bind local:HomeView.Current.DescriptionFontSize.Value, Mode=OneWay}" />
   </Grid>
</DataTemplate>

So now with this we can bind double values and get their updates on the go, and if we have values, can we have any other type. Why not a generic object, let’s continue defining GeneryProperty:

public class GenericProperty : DependencyObject
{
    public object Value
    {
        get { return (object)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register(nameof(Value), typeof(object), typeof(GenericProperty), 
            new PropertyMetadata(DependencyProperty.UnsetValue));
}

In the page resources section let’s add a Brush:

<c:GenericProperty x:Name="CustomColor" x:Key="CustomColor">
    <c:GenericProperty.Value>
      <SolidColorBrush Color="Blue"/>
   </c:GenericProperty.Value>
</c:GenericProperty>

And in the Visual States Section:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="VisualStates" >
        <VisualState x:Name="Full">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="600" />
            </VisualState.StateTriggers>
                </VisualState>
                <VisualState x:Name="Small">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="DescriptionFontSize.Value" Value="12"/>
                        <Setter Target="HeaderFontSize.Value" Value="18"/>
                        <Setter Target="CustomColor.Value">
                            <Setter.Value>
                                <SolidColorBrush Color="Orange"/>
                            </Setter.Value>
                        </Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

And finally, having casting in compiled binding, we can do the following:

<Grid  Background="{x:Bind (Brush)local:HomeView.Current.CustomColor.Value, Mode=OneWay}" >
...
</Grid>

I have tested this with the latest insider release 14905, I understand it works from the Anniversary Update.

Conclusions

This is just the beginning, now we have methods and casting, we can make practically everything directly from XAML just adding that Current property. I think this article solves plenty of questions about DynamicResources, how to bind a resource, etc.

You can get the source here CompiledBindingExamples

Hope you find it useful and as always follow me at @juanpaexpedite to know interesting UWP stuff. Now I am preparing a new dev oriented App I hope finish it in few weeks.