Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML...

44

Transcript of Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML...

Page 1: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.
Page 2: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Jason MorsePrincipal Engineering ManagerOffice Core Experience TeamPutting it all together, Office & XAML

XAML Case Study: Putting it All Together, Office and XAML

2-776

Andrew CoatesSenior Software EngineerOffice Core Experience Team

Page 3: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Office values and goalsApproach to universal applicationsWhere we are today

Agenda

Page 4: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

How do you use XAML if you don’t care about easy?

Page 5: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

There are many adjectives people use to describe Office…

Functional, powerful, productive, feature rich, complicated…

Fast and light are not usually among them.

First a bit of background on Office

Page 6: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

All native, mostly C++• Hails from pre-C++ days over 30 years ago.• Continues to evolve with rapid adoption of C+

+11.

It has grown progressively in that time• Up to about 171 million lines at last count .• Not just Word, Excel, PowerPoint anymore.

Most versions on other platforms have been forks• These aren’t included in the 171 million lines.

The Office codebase

Page 7: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Originally we sold Office for machines.• Increasingly we are selling to

people.

What does this mean?• Available wherever you are.• Consistent experience.• New features need to roll out

everywhere.

The business has changed

Page 8: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Changing the adjectives• Fast & fluid• Still powerful

Sharing code• Leveraging what we have for new platforms.• Maximize code sharing between platforms.• Still use enough platform specific code to

guarantee the best experience possible on that platform.

We do care about development speed…• But complex and expensive solutions are fine as

long as we can centralize them.

So what do we care about?

Page 9: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Traditional databinding is too slow.• Set data into controls in code-behind.• x:Bind does a great job of addressing this, use it!

Don’t make every property a DP.• Custom DependencyProperties are significantly slower than

built-in ones.

Use only as many elements as you need.• Collapsed trees still have cost.• Either load optional elements dynamically or use

x:DeferLoadStrategy.• Previously VSM would create extraneous DependencyObjects.

Don’t be afraid of code-behind!

Using XAML at the speed of light

In the Windows 8.1 timeframe we looked at how we could squeeze every ounce of performance out of XAML.

Page 10: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

So {Binding} is not super fast• When we started x:Bind did not exist• Push data into XAML using code behind• Code behind can interact directly with native C++ types

Wanted a binding replacement to help write repetitive code-behind

How we work with data in XAML

Page 11: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

We call this XAML scriptingPreprocess the XAML file during a pre-build stepCustom XAML markup defines:• Properties.• “Scripts”, to push data into the XAML elements.• Define when each script should run.

Generate code-behind from the markupXAML team used same concept for x:Bind design

A solution based on custom XAML markup

Page 12: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

<o:Property Type="Unicorn" Name="User"/>

<o:Script Trigger="User.Name"> tb->Text = User->Name;</o:Script>

<TextBlock x:Name="tb" />

Roughly the same as:<TextBlock Text="{x:Bind User.Name, Mode=OneWay}"/>

A quick glimpse at Office’s XAML scripting

Page 13: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

The Good• Similar performance gains as we can now get from

x:Bind.• Switching yielded 50% faster boot for Calendar.

Unintended side effects• Meant to be just for pushing data.• Too easy to write logic in the UI.• Logic becomes platform specific.• Hard to unit test.

Scripting side-effects

Sometimes what happens and what you think will happen aren’t quite the same.

Page 14: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Business logic should be separate from UI code• Always been important.• Even more so in todays cross platform world.

Encapsulated in its own object• The UI can communicate directly with this object.• Object to UI communications should be through events.

This allows the object to be shared

Metapoint on how to build UI

Page 15: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

• Model defined in a markup language.

• Generates a base class and platform specific interop layers.

• Developer fills in ViewModel implementation.

Moving to markup generated ViewModels

Model Definition

Generated ViewModel

XAML Interop(INPC)

XAML UI

JNI Interop

Java UI

iOS Interop

iOS UI

Unit Tests

MDL

Generated Base

Interop Layers

Platform Specific UI

Page 16: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Great for XAML to C++ interop• Makes writing code against XAML dramatically

easier.• Generates winmd interfaces for you.

Has some drawbacks to be aware of• Can mask complexity or cost.• Some limits on how C++ can be integrated.• Not cross platform.

Works great as a thin interop layer

C++CX is the glue for C++ apps

Overview of C++CX pros and cons.

Page 17: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Understanding C++CX classes

public ref class Foo sealed : public IBar{public: // public class properties/methods property int Number; void FooMethod();

// Ibar method override virtual void BarMethod() override;

internal:

void NativeMethod(CppModel* model);

private: CppModel* m_model;};

class Foo : public RuntimeClass<__IFooPublicNonVirtuals,

IBar>{public: // __IFooPublicNonVirtuals interface methods virtual HRESULT get_Number(int* num) override; virtual HRESULT put_Number(int num) override; virtual HRESULT FooMethod() override;

// IBar methods virtual HRESULT BarMethod() override;

void NativeMethod(SomeCPPStruct* model);

private: CppModel* m_model;};

C++CX C++ (using WRL)

Page 18: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

// some simple code…control->RenderTransform->X = 25.0;

// turns intocontrol->QueryInterface(IID_PPV_ARGS(pUIE.GetAddressOf()));pUIE->get_RenderTransform(&pTransform);pTransform->QueryInterface( IID_PPV_ARGS(pTranslate.GetAddressOf()));pTranslate->put_X(25.0);

// what’s so bad? Well…If (control->RenderTransform->X != newTransformX) control->RenderTransform->X = newTransformX; If (control->RenderTransform->Y != newTransformY) control->RenderTransform->Y = newTransformY;

Understanding what C++CX generates

It’s so easy! What could possibly go wrong?

Page 19: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

C++ types can be used natively in CX• The issue is how to get those objects in the first place.

In the same binary it’s easy• Can call internal functions directly.

Across binaries it is harder• Calls out work so you can use a locator pattern.• Object^ can be typecast to IInspectable* via reinterpret_cast.• Exported setter functions are a pattern we use a lot.

__dllexport void SetModel(C^ c, const Model& m){ c->SetModel(m);}

Using C++ types in ref classes

Main strategies for handling native types from within ref classes.

Page 20: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Let’s say you have a C++ class you want to expose to x:Bind

class UnicornImpl{public:void RegisterPropChanged(function<void(int)>&);wstring GetName();

};

Composing C++ classes

Page 21: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

ref class UnicornCX : BaseINPC{ UnicornCX() : m_native(make_shared<UnicornImpl>) { m_native.RegisterPropChanged([=]( int propId) { if (propId == idName) NotifyPropertyChanged(“Name”);}); } property Name { String^ get { return ref new String(m_native.GetName().c_str()); }}shared_ptr<UnicornImpl> m_native;

}

Wrapping with CX

Page 22: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

How about if you really want to use full inheritance in C++?

Page 23: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

import “Windows.Foundation.idl”;[uuid(…)][exclusiveto(Unicorn)]interface IUnicorn : IInspectable{ [propget] HRESULT Name([out, retval] HSTRING*v);}

runtimeclass Unicorn{ interface IUnicorn; interface INotifyPropertyChanged;}

With C++ first generate a header and winmdFun with SDK tools:1. Make an IDL2. Run it

through midl /winrt to create a header and .winmd file.

3. mdmerge.exe allows merging with your own winmd files.

Page 24: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

class UnicornWRL : RuntimeClass<IUnicorn, INPCImpl, UnicornImpl>{ UnicornWRL() { RegisterPropChanged([](int propId) { if (propId == idName) NotifyPropertyChanged(HStringReference(L“Name”).Get());}); } STDMETHODIMP get_Name(HSTRING* value){ return HStringReference(GetName().c_str()).CopyTo(value); }}}

Now use WRL to inherit from your base class

Page 25: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Use CustomResource loader• Can load resources from our existing resource

pipelines.• As an example, for colors:

Background=“{OfficeBrush PaneBackground}” becomes:

Background=“{CustomResource Brush.123}”

• Preprocessing the XAML to put an int in the XAML saves us from doing string lookups at runtime.

We use this for string resource lookups, colors, command ID lookups, etc.

Integrating non-XAML resources

One of our earliest changes was creating a custom build tool to perform simple transformations on XAML files.

Page 26: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

inline IXamlType^ __XamlTypeInfo_CreateType_MyEnum(XamlTypeInfoProvider^ provider){ XamlUserType^ userType = ref new XamlUserType(provider, L"MyEnum",

provider->GetXamlTypeByName(L"System.Enum")); userType->KindOfType = Interop::TypeKind::Metadata; userType->FromStringConverter = [](XamlUserType^ userType, String^ input) -> Object^ { uint32 enumValue = userType->CreateEnumUIntFromString(input); return ref new Platform::Box<MyEnum>((MyEnum)enumValue); }; userType->AddEnumValue(L"Option1", PropertyValue::CreateInt32(MyEnum::Option1)); userType->AddEnumValue(L"Option2", PropertyValue::CreateInt32(MyEnum::Option2)); return userType;}__XamlTypeInfoMap_IXamlType(L"MyEnum", __XamlTypeInfo_CreateType_MyEnum);

Why not put it all in an enum?

Page 27: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Icon control is a UserControl with no XAML file• All contents are generated via code.• Internals are abstracted from users.

We switched to colored fonts instead of images• Glyphs now support colored fonts and are more efficient than

TextBlock.• This allows a single asset to support multiple sizes.• Can still use PNGs for targeted cases.

public ref class Icon sealed : public UserControl{public: property uint16 Id { uint16 get(); void set… property IconSize Size { IconsSize get(); void set…};

Office Icon control

How we load icons for commands in Office.

Page 28: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Icon lookup logic<core:Icon Id=“{= msotcidFoo}” Size=“{= ImageSize::Square20}”/>

<core:Icon>

Look up ID metadata

Use primary font

Use language

specific font

control boot

CreateGlyphs

CreateImage

Get target image file

Insert in Icon.Conten

t

Page 29: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

What about very custom UI?

Page 30: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Highly sophisticated, dynamic, animated, interactive content.• Rendered using DirectX since Office 2013.• Content is rendered in 2d layers which are then

composed.

XAML has a great solution here!• SurfaceImageSource, VirtualSurfaceImageSource

and SwapChainPanel enable integrating DirectX content.

• Can be transparently composed with XAML UI.• Allows for seamless animations and smooth

scrolling.

Office document canvases

The architectural approach to the document canvases where fidelity of look and feel is absolutely critical.

Page 31: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Application Thread

UI Thread Compositor Thread

Rendering Cross Platform Architecture

Channel

WinRT BackendXAML

Direct Compositio

n

Channel

Android BackendJava Views

Channel

In-Process Direct3D

Compositor

iOS & MacFrontend talks directly with Core Animation

Core Animation

Win32

XAML

Android

iOS OSX

Shared C++Layout

Rendering

AirSpace Frontend

Some Code

Sharing +

Platform-Specific Forking

Page 32: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

• All animations should run on the composition thread - independent of UI

Animating our UI

ThemeTransitions• Easy• Implicit• Limited customization

Storyboards• Fully customizable• Verbose• Difficult to make

consistent• Require Custom

Triggers

Page 33: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Animation panel demo

Page 34: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Flexibility and power of storyboards• Our animations can use any timing curve.• Multiple KeyFrames.

Uses Office’s existing animation definitions• Office defines a set of animation types as an

AnimationClass.• Animation definitions can then be shared across

platforms.

Animations triggered on reposition, show and hide

Integrating animations into a custom panel Office Panel creates implicit, fluid, flexible and interruptible animations.

Page 35: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Developers can customize animations through custom and attached properties• The animation is determined by the AnimationClass

property on the panel.• Or from an AnimationClassOverride attached

property on the specific element.

Our Panel implements MeasureOverride and ArrangeOverrideDynamically generates storyboards during arrange

Implicit animations

Triggering animation automatically makes creating fluid UI easier

Page 36: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

child.Arrange(newPos);

Storyboard s = new Storyboard();DoubleAnimation daX = new DoubleAnimation() { From = oldPos.X – newPos.X, To = 0 };DoubleAnimation daY = new DoubleAnimation() { From = oldPos.Y – newPos.Y, To = 0 };Storyboard.SetTarget(daX, child.RenderTransform);Storyboard.SetTarget(daY, child.RenderTransform);Storyboard.SetTargetProperty(daX, "X");Storyboard.SetTargetProperty(daY, "Y");s.Children.Add(daX);s.Children.Add(daY);s.Begin();

What happens if the position changes while an animation is in progress?

Animating from old position to new

Page 37: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Positioning content entirely with RenderTransform

child.Arrange({0, 0}, finalSize);Storyboard s = new Storyboard();DoubleAnimation daX = new DoubleAnimation() { To = newPos.X };DoubleAnimation daY = new DoubleAnimation() { To = newPos.Y };Storyboard.SetTarget(daX, child.RenderTransform);Storyboard.SetTarget(daY, child.RenderTransform);Storyboard.SetTargetProperty(daX, "X");Storyboard.SetTargetProperty(daY, "Y");s.Children.Add(daX);s.Children.Add(daY);s.Begin();

Accounting for interruptions

No From Specifie

d

Always arrang

e at 0,0

Page 38: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Normally resize doesn’t animate in XAML• To animate resize you have to turn on UseDependantAnimations.• Could use ScaleTransform but that stretches the content.

Our solution: split content into multiple layers• All our items have been arranged with RenderTransforms.• Use ScaleTransform on backgrounds and borders.• Allow content to animate to new layout.• Triggered during arrange in response to layout changes.

Resize animations

Page 39: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

Word, Excel, PowerPoint, OneNote and the new Mail and Calendar apps are shipping soon.• They are built on the public platform.• Still work to do but they are looking great.

The Win10 platform improvements will make them even better!• We are working on integrating new platform features right now.

We invented our own databinding replacement…• But if x:Bind had existed we wouldn’t have felt the need.

Universal Office applications today

Page 40: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

• One package for mobile and desktop.

• Adapt to changes on the fly.• Use consistent crossover

points.• Layer things appropriately.

• Keep child elements self-contained.• The switch often just involves laying them out

differently.• Build external communication around what you

want it to do, not how it is set up.

They are truly universal apps

Page 41: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

This code is not based on a fork.It is the same tree that produces Win32 Office and our web applications.It now also includes the Android tablet versions of Word, Excel and PowerPoint.

Universal is built out of our main tree

Page 42: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

96%

4%

Universal

Shared Endpoint

95%

5%Android

Shared Endpoint

• Universal is built from

• 96% shared code (by LoC)• including the XAML files and related

code-behind. • If you exclude the XAML pieces, then

Universal is built from:

• 98.6% shared code.

• Android is built from

• 95% shared code (by LoC)• including the Java files and related code-

behind.• If you exclude the Java pieces, then

Android is builtfrom:

• 99.7% shared code.

So how much code are we sharing?

Page 43: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

• XAML Session 635: Data Binding: Boost Your App’s Performance Through New Enhancements to XAML Data Binding

• XAML Session 689: XAML Performance: Techniques for maximizing Universal App experiences build with XAML

• Microsoft Office Cross-Platform Architecture - @Scale 2014

Call to Action

Page 44: Platform Specific UI Interop Layers Generated Base MDL Model Definition Generated ViewModel XAML Interop (INPC) XAML UIJNI InteropJava.

© 2015 Microsoft Corporation. All rights reserved.