Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet1.bmp
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet2.bmp
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet3.bmp
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet4.bmp
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet5.bmp
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet6.bin
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet7.bin
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet8.bin
Binary file not shown.
Binary file added WinUIGallery/Assets/SceneNode/DamagedHelmet9.bin
Binary file not shown.
3 changes: 2 additions & 1 deletion WinUIGallery/Controls/ControlExample.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,12 @@
<!-- Sample code display -->
<Expander
Grid.Row="1"
Padding="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
CornerRadius="0,0,8,8"
Padding="0">
Visibility="{x:Bind SourceCodeVisibility, Mode=OneWay}">

<Expander.Header>
<TextBlock Text="Source code" />
Expand Down
7 changes: 7 additions & 0 deletions WinUIGallery/Controls/ControlExample.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ public int WebViewWidth
set { SetValue(HorizontalContentAlignmentProperty, value); }
}

public static readonly DependencyProperty SourceCodeVisibilityProperty = DependencyProperty.Register("SourceCodeVisibility", typeof(Visibility), typeof(ControlExample), new PropertyMetadata(Visibility.Visible));
public Visibility SourceCodeVisibility
{
get { return (Visibility)GetValue(SourceCodeVisibilityProperty); }
set { SetValue(SourceCodeVisibilityProperty, value); }
}

public ControlExample()
{
this.InitializeComponent();
Expand Down
62 changes: 62 additions & 0 deletions WinUIGallery/Samples/ControlPages/ContentIslandPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="WinUIGallery.ControlPages.ContentIslandPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:WinUIGallery.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:layouts="using:WinUIGallery.Layouts"
xmlns:local="using:WinUIGallery.ControlPages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<Style x:Key="CardRectangleStyle" TargetType="Rectangle">
<Style.Setters>
<Setter Property="Stroke" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
<Setter Property="StrokeThickness" Value="1" />
<Setter Property="Width" Value="400" />
<Setter Property="Height" Value="400" />
<Setter Property="Fill" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
<Setter Property="RadiusX" Value="8" />
<Setter Property="RadiusY" Value="8" />
<Setter Property="Margin" Value="8" />
</Style.Setters>
</Style>
</Grid.Resources>
<controls:ControlExample HeaderText="A basic content dialog with content." SourceCodeVisibility="Collapsed">
<controls:ControlExample.Example>
<Grid RowSpacing="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Here's an ContentIsland in a ScrollViewer. Notice now the content scrolls and clips correctly." />
<Button
Grid.Row="1"
Click="LoadModel_Click"
Content="Load model"
Style="{StaticResource AccentButtonStyle}" />
<layouts:WrapPanel
x:Name="_rectanglePanel"
Grid.Row="2"
HorizontalAlignment="Left">
<Rectangle Style="{StaticResource CardRectangleStyle}" />
<Rectangle Grid.Column="1" Style="{StaticResource CardRectangleStyle}" />
<Rectangle Grid.Row="1" Style="{StaticResource CardRectangleStyle}" />
<Rectangle
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource CardRectangleStyle}" />
<Rectangle Grid.Row="2" Style="{StaticResource CardRectangleStyle}" />
<Rectangle
Grid.Row="2"
Grid.Column="1"
Style="{StaticResource CardRectangleStyle}" />
</layouts:WrapPanel>
</Grid>
</controls:ControlExample.Example>
</controls:ControlExample>
</Grid>
</Page>
75 changes: 75 additions & 0 deletions WinUIGallery/Samples/ControlPages/ContentIslandPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Numerics;
using Microsoft.UI.Composition;
using Microsoft.UI.Content;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Shapes;

namespace WinUIGallery.ControlPages;

public sealed partial class ContentIslandPage : Page
{
public ContentIslandPage()
{
this.InitializeComponent();
}

int idx = 0;

Rectangle GetNextHostElement()
{
if (idx < _rectanglePanel.Children.Count)
{
return ((Rectangle)_rectanglePanel.Children[idx++]);
}

return null;
}

public async void LoadModel()
{
ContentIsland parentIsland = this.XamlRoot.ContentIsland;

Rectangle rect = GetNextHostElement();
if (rect == null)
{
return;
}

ContainerVisual placementVisual = (ContainerVisual)ElementCompositionPreview.GetElementVisual(rect);
Vector2 size = rect.ActualSize;

ChildSiteLink childSiteLink = ChildSiteLink.Create(parentIsland, placementVisual);

// We also need to keep the offset of the ChildContentLink within the parent ContentIsland in sync
// with that of the placementElement for UIA to work correctly.
var layoutUpdatedEventHandler = new EventHandler<object>((s, e) =>
{
// NOTE: Do as little work in here as possible because it gets called for every
// xaml layout change on this thread!
var transform = rect.TransformToVisual(null);
var point = transform.TransformPoint(new Windows.Foundation.Point(0, 0));
childSiteLink.LocalToParentTransformMatrix = System.Numerics.Matrix4x4.CreateTranslation(
(float)(point.X),
(float)(point.Y),
0);
});
rect.LayoutUpdated += layoutUpdatedEventHandler;
layoutUpdatedEventHandler.Invoke(null, null);

placementVisual.Size = size;
childSiteLink.ActualSize = size;

ContentIsland helmetIsland = await HelmetScenario.CreateIsland(placementVisual.Compositor);

childSiteLink.Connect(helmetIsland);
}

private void LoadModel_Click(object sender, RoutedEventArgs e)
{
_rectanglePanel.Visibility = Visibility.Visible;
LoadModel();
}
}
16 changes: 16 additions & 0 deletions WinUIGallery/Samples/Data/ControlInfoData.json
Original file line number Diff line number Diff line change
Expand Up @@ -3668,6 +3668,22 @@
"FilePicker"
]
},
{
"UniqueId": "ContentIsland",
"Title": "ContentIsland",
"ApiNamespace": "Microsoft.UI.Content",
"Subtitle": "Create ContentIslands to host other frameworks in your app.",
"ImagePath": "ms-appx:///Assets/ControlImages/ContentIsland.png",
"Description": "Create ContentIslands to host other frameworks in your app.",
"Content": "<p>Look at the <i>ContentIslandPage.xaml</i> file in Visual Studio to see the full code for this page.</p>",
"IsNew": true,
"Docs": [
{
"Title": "ContentIsland - API",
"Uri": "https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.content.contentisland"
}
]
},
{
"UniqueId": "FilePicker",
"Title": "FilePicker",
Expand Down
152 changes: 152 additions & 0 deletions WinUIGallery/Samples/SampleHelpers/SceneNode/HelmetScenario.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Numerics;
using System.Threading.Tasks;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.UI.Composition;
using Microsoft.Graphics.DirectX;
using Microsoft.UI.Composition;
using Microsoft.UI.Composition.Scenes;
using Microsoft.UI.Content;

class HelmetScenario
{
public static async Task<ContentIsland> CreateIsland(Compositor compositor)
{
var visual = await LoadScene_DamagedHelmet(compositor);

var island = ContentIsland.Create(visual);
return island;
}

private static async Task<Visual> LoadScene_DamagedHelmet(Compositor compositor)
{
// Initialize Win2D, used for loading bitmaps.

var canvasDevice = new CanvasDevice();
var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(
compositor, canvasDevice);

// Create the Visuals and SceneNode structure, along with default rotation animations.

var sceneVisual = SceneVisual.Create(compositor);
sceneVisual.RelativeOffsetAdjustment = new Vector3(0.5f, 0.5f, 0.0f);

var worldNode = SceneNode.Create(compositor);
sceneVisual.Root = worldNode;

var rotateAngleAnimation = compositor.CreateScalarKeyFrameAnimation();
rotateAngleAnimation.InsertKeyFrame(0.0f, 0.0f);
rotateAngleAnimation.InsertKeyFrame(0.5f, 360.0f);
rotateAngleAnimation.InsertKeyFrame(1.0f, 0.0f);
rotateAngleAnimation.Duration = TimeSpan.FromSeconds(15);
rotateAngleAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
worldNode.Transform.RotationAxis = new Vector3(0, 1, 0);
worldNode.Transform.StartAnimation("RotationAngleInDegrees", rotateAngleAnimation);

var sceneNode0 = SceneNode.Create(compositor);
sceneNode0.Transform.Scale = new Vector3(170);
sceneNode0.Transform.Orientation = new Quaternion(0.70710683f, 0.0f, 0.0f, 0.70710683f);
worldNode.Children.Add(sceneNode0);

var sceneNodeForTheGLTFMesh0 = SceneNode.Create(compositor);
sceneNode0.Children.Add(sceneNodeForTheGLTFMesh0);

// Load all file data in parallel:
// - Although Scene Graph objects prefer a UI thread, Win2D can load and create the bitmaps
// on parallel background threads.

var vertexData = SceneNodeCommon.LoadMemoryBufferFromUriAsync(
"Assets/SceneNode/DamagedHelmet6.bin");

var normalData = SceneNodeCommon.LoadMemoryBufferFromUriAsync(
"Assets/SceneNode/DamagedHelmet7.bin");

var texCoordData = SceneNodeCommon.LoadMemoryBufferFromUriAsync(
"Assets/SceneNode/DamagedHelmet8.bin");

var indexData = SceneNodeCommon.LoadMemoryBufferFromUriAsync(
"Assets/SceneNode/DamagedHelmet9.bin");

var canvasBitmap0 = SceneNodeCommon.LoadIntoCanvasBitmap(
canvasDevice, "Assets/SceneNode/DamagedHelmet1.bmp");

var canvasBitmap1 = SceneNodeCommon.LoadIntoCanvasBitmap(
canvasDevice, "Assets/SceneNode/DamagedHelmet2.bmp");

var canvasBitmap2 = SceneNodeCommon.LoadIntoCanvasBitmap(
canvasDevice, "Assets/SceneNode/DamagedHelmet3.bmp");

var canvasBitmap3 = SceneNodeCommon.LoadIntoCanvasBitmap(
canvasDevice, "Assets/SceneNode/DamagedHelmet4.bmp");

var canvasBitmap4 = SceneNodeCommon.LoadIntoCanvasBitmap(
canvasDevice, "Assets/SceneNode/DamagedHelmet5.bmp");

await vertexData;
await normalData;
await texCoordData;
await indexData;
await canvasBitmap0;
await canvasBitmap1;
await canvasBitmap2;
await canvasBitmap3;
await canvasBitmap4;


// Generate mipmaps from the bitmaps, which are needed for 3D rendering.

var materialInput0 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap0.Result);
var materialInput1 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap1.Result);
var materialInput2 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap2.Result);
var materialInput3 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap3.Result);
var materialInput4 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap4.Result);


// Copy loaded binary data into mesh: verticies, normals, ...

var mesh0 = SceneMesh.Create(compositor);
mesh0.PrimitiveTopology = DirectXPrimitiveTopology.TriangleList;
mesh0.FillMeshAttribute(SceneAttributeSemantic.Vertex, DirectXPixelFormat.R32G32B32Float, vertexData.Result);
mesh0.FillMeshAttribute(SceneAttributeSemantic.Normal, DirectXPixelFormat.R32G32B32Float, normalData.Result);
mesh0.FillMeshAttribute(SceneAttributeSemantic.TexCoord0, DirectXPixelFormat.R32G32Float, texCoordData.Result);
mesh0.FillMeshAttribute(SceneAttributeSemantic.Index, DirectXPixelFormat.R16UInt, indexData.Result);


// Initialize the material with different texture inputs (color, roughness, normals, ...)

var sceneMaterial0 = SceneMetallicRoughnessMaterial.Create(compositor);

var renderComponent0 = SceneMeshRendererComponent.Create(compositor);
renderComponent0.Mesh = mesh0;
renderComponent0.Material = sceneMaterial0;
sceneNodeForTheGLTFMesh0.Components.Add(renderComponent0);

sceneMaterial0.BaseColorFactor = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
sceneMaterial0.BaseColorInput = SceneNodeCommon.CreateMaterial(
compositor, materialInput0, renderComponent0, "BaseColorInput"); ;

sceneMaterial0.RoughnessFactor = 1.0f;
sceneMaterial0.MetallicFactor = 1.0f;
sceneMaterial0.MetallicRoughnessInput = SceneNodeCommon.CreateMaterial(
compositor, materialInput1, renderComponent0, "MetallicRoughnessInput");

sceneMaterial0.NormalScale = 1.0f;
sceneMaterial0.NormalInput = SceneNodeCommon.CreateMaterial(
compositor, materialInput2, renderComponent0, "NormalInput");

sceneMaterial0.OcclusionStrength = 1.0f;
sceneMaterial0.OcclusionInput = SceneNodeCommon.CreateMaterial(
compositor, materialInput3, renderComponent0, "OcclusionInput");

sceneMaterial0.AlphaMode = SceneAlphaMode.Opaque;
sceneMaterial0.IsDoubleSided = false;
sceneMaterial0.EmissiveFactor = new Vector3(1.0f, 1.0f, 1.0f);
sceneMaterial0.EmissiveInput = SceneNodeCommon.CreateMaterial(
compositor, materialInput4, renderComponent0, "EmissiveInput");

return sceneVisual;
}
}
Loading