diff --git a/Samples/Content/cpp-win32/Squares/DrawingIsland.cpp b/Samples/Content/cpp-win32/Squares/DrawingIsland.cpp deleted file mode 100644 index 0f70676b3..000000000 --- a/Samples/Content/cpp-win32/Squares/DrawingIsland.cpp +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include "pch.h" - -#include "DrawingIsland.h" -#include "NodeSimpleFragment.h" -#include "IslandFragmentRoot.h" - -namespace Squares -{ - DrawingIsland::DrawingIsland( - const winrt::Compositor& compositor) - { - m_compositor = compositor; - - m_island = winrt::ContentIsland::Create(compositor); - - Output_Initialize(); - Input_Initialize(); - Accessibility_Initialize(); - Window_Initialize(); - } - - - DrawingIsland::~DrawingIsland() - { - m_fragmentRoot = nullptr; - m_fragmentFactory = nullptr; - m_compositor = nullptr; - } - - - void - DrawingIsland::Close() - { - m_visuals = nullptr; - m_selectedVisual = nullptr; - m_backgroundBrushDefault = nullptr; - m_backgroundBrushA = nullptr; - m_backgroundBrushB = nullptr; - m_backgroundBrushC = nullptr; - m_backgroundVisual = nullptr; - - // Destroy Content: - m_island.Close(); - m_island = nullptr; - } - - - void - DrawingIsland::Output_Initialize() - { - for (int i = 0; i < _countof(m_colorBrushes); i++) - { - m_colorBrushes[i] = m_compositor.CreateColorBrush(s_colors[i]); - - winrt::Color halfTransparent = s_colors[i]; - halfTransparent.A = 0x80; - m_halfTransparentColorBrushes[i] = m_compositor.CreateColorBrush(halfTransparent); - } - - // Create the background parent Visual that the individual square will be added into. - m_backgroundBrushDefault = m_compositor.CreateColorBrush(winrt::Color{ 0x99, 0x20, 0x20, 0x20 }); - m_backgroundBrushA = m_compositor.CreateColorBrush(winrt::Color{ 0x99, 0x99, 0x20, 0x20 }); - m_backgroundBrushB = m_compositor.CreateColorBrush(winrt::Color{ 0x99, 0x20, 0x99, 0x20 }); - m_backgroundBrushC = m_compositor.CreateColorBrush(winrt::Color{ 0x99, 0x20, 0x20, 0x99 }); - - m_backgroundVisual = m_compositor.CreateSpriteVisual(); - m_backgroundVisual.Brush(m_backgroundBrushDefault); - m_backgroundVisual.RelativeSizeAdjustment(winrt::float2(1, 1)); - m_island.Root(m_backgroundVisual); - - winrt::ContainerVisual drawingVisualsRoot = m_compositor.CreateContainerVisual(); - m_visuals = drawingVisualsRoot.Children(); - m_backgroundVisual.Children().InsertAtTop(drawingVisualsRoot); - } - - - void - DrawingIsland::Output_AddVisual( - winrt::float2 const point, - bool halfTransparent) - { - winrt::SpriteVisual visual = m_compositor.CreateSpriteVisual(); - visual.Brush(halfTransparent ? - m_halfTransparentColorBrushes[m_currentColorIndex] : - m_colorBrushes[m_currentColorIndex]); - - m_currentColorIndex = (m_currentColorIndex + 1) % 4; - - float const BlockSize = 30.0f; - visual.Size({ BlockSize, BlockSize }); - visual.Offset({ point.x - BlockSize / 2.0f, point.y - BlockSize / 2.0f, 0.0f }); - - m_visuals.InsertAtTop(visual); - - m_selectedVisual = visual; - m_offset.x = -BlockSize / 2.0f; - m_offset.y = -BlockSize / 2.0f; - - CreateUIAProviderForVisual(); - - Accessibility_UpdateScreenCoordinates(m_selectedVisual); - } - - - void - DrawingIsland::Input_Initialize() - { - auto pointerSource = winrt::InputPointerSource::GetForIsland(m_island); - - pointerSource.PointerPressed( - [this](winrt::InputPointerSource const&, - winrt::PointerEventArgs const& args) - { - auto currentPoint = args.CurrentPoint(); - auto properties = currentPoint.Properties(); - - if (properties.IsLeftButtonPressed()) - { - Input_OnLeftButtonPressed(args); - } - }); - - pointerSource.PointerMoved( - [this](winrt::InputPointerSource const&, - winrt::PointerEventArgs const& args) - { - Input_OnPointerMoved(args); - }); - - pointerSource.PointerReleased( - [&](auto&& ...) - { - Input_OnPointerReleased(); - }); - - // Set up the keyboard source. We store this in a member variable so we can easily call - // TrySetFocus() in response to left clicks in the content later on. - m_keyboardSource = winrt::InputKeyboardSource::GetForIsland(m_island); - - m_keyboardSource.KeyDown( - [this](winrt::InputKeyboardSource const&, - winrt::KeyEventArgs const& args) - { - bool handled = Input_OnKeyDown(args.VirtualKey()); - - // Mark the event as handled - if (handled) - { - args.Handled(true); - } - }); - - auto activationListener = winrt::InputActivationListener::GetForIsland(m_island); - (void)activationListener.InputActivationChanged( - [this, activationListener]( - winrt::InputActivationListener const&, - winrt::InputActivationListenerActivationChangedEventArgs const&) - { - switch (activationListener.State()) - { - case winrt::InputActivationState::Activated: - m_backgroundVisual.Opacity(1.0f); - break; - - default: - m_backgroundVisual.Opacity(0.5f); - break; - } - }); - } - - - bool - DrawingIsland::Input_OnKeyDown( - winrt::Windows::System::VirtualKey virtualKey) - { - bool handled = false; - - switch (virtualKey) - { - case winrt::VirtualKey::A: - { - m_backgroundVisual.Brush(m_backgroundBrushA); - handled = true; - break; - } - - case winrt::VirtualKey::B: - { - m_backgroundVisual.Brush(m_backgroundBrushB); - handled = true; - break; - } - - case winrt::VirtualKey::C: - { - m_backgroundVisual.Brush(m_backgroundBrushC); - handled = true; - break; - } - - case winrt::VirtualKey::Space: - { - m_backgroundVisual.Brush(m_backgroundBrushDefault); - break; - } - } - - return handled; - } - - winrt::Visual - DrawingIsland::HitTestVisual( - winrt::float2 const point) - { - winrt::Visual selectedVisual{ nullptr }; - for (winrt::Visual visual : m_visuals) - { - winrt::float3 const offset = visual.Offset(); - winrt::float2 const size = visual.Size(); - - if (point.x >= offset.x && - point.x < offset.x + size.x && - point.y >= offset.y && - point.y < offset.y + size.y) - { - selectedVisual = visual; - } - } - - return selectedVisual; - } - - - void - DrawingIsland::Input_OnLeftButtonPressed( - const winrt::PointerEventArgs& args) - { - // Left button manipulates the custom-drawn content - winrt::float2 const point = args.CurrentPoint().Position(); - - bool controlPressed = WI_IsFlagSet( - args.KeyModifiers(), - winrt::Windows::System::VirtualKeyModifiers::Control); - - OnLeftClick(point, controlPressed); - } - - - void - DrawingIsland::Input_OnPointerReleased() - { - m_selectedVisual = nullptr; - } - - - void - DrawingIsland::OnLeftClick( - const winrt::float2 point, - bool controlPressed) - { - m_selectedVisual = HitTestVisual(point); - - if (m_selectedVisual) - { - winrt::float3 const offset = m_selectedVisual.Offset(); - - m_offset.x = offset.x - point.x; - m_offset.y = offset.y - point.y; - - m_visuals.Remove(m_selectedVisual); - m_visuals.InsertAtTop(m_selectedVisual); - } - else - { - Output_AddVisual(point, controlPressed); - } - - m_keyboardSource.TrySetFocus(); - } - - - void - DrawingIsland::Input_OnPointerMoved( - const winrt::PointerEventArgs& args) - { - if (m_selectedVisual) - { - winrt::float2 const point = args.CurrentPoint().Position(); - m_selectedVisual.Offset({ point.x + m_offset.x, point.y + m_offset.y, 0.0f }); - } - } - - - void - DrawingIsland::Accessibility_Initialize() - { - m_fragmentRoot = winrt::make_self(m_island); - m_fragmentRoot->SetName(L"Content Island"); - - m_fragmentFactory = winrt::make_self(); - - - (void)m_island.AutomationProviderRequested( - [this](winrt::ContentIsland const& sender, - winrt::ContentIslandAutomationProviderRequestedEventArgs const& args) - { - return Accessibility_OnAutomationProviderRequested(sender, args); - }); - } - - - void - DrawingIsland::Accessibility_OnAutomationProviderRequested( - const winrt::ContentIsland& /*island*/, - const winrt::ContentIslandAutomationProviderRequestedEventArgs& args) - { - IInspectable providerAsIInspectable; - m_fragmentRoot->QueryInterface(winrt::guid_of(), winrt::put_abi(providerAsIInspectable)); - args.AutomationProvider(std::move(providerAsIInspectable)); - - args.Handled(true); - } - - - void - DrawingIsland::Accessibility_UpdateScreenCoordinates(winrt::Visual visual) - { - winrt::Rect logicalRect; - logicalRect.X = visual.Offset().x; - logicalRect.Y = visual.Offset().y; - logicalRect.Width = visual.Size().x; - logicalRect.Height = visual.Size().y; - - auto fragment = m_visualToFragmentMap[visual]; - - // This will convert from the logical coordinate space of the ContentIsland to - // Win32 screen coordinates that are needed by Accesibility. - auto screenRect = m_island.Coordinates().ComputeScreenCoordinates(logicalRect); - - UiaRect uiaRect; - uiaRect.left = screenRect.X; - uiaRect.top = screenRect.Y; - uiaRect.width = screenRect.Width; - uiaRect.height = screenRect.Height; - - fragment->SetBoundingRects(uiaRect); - } - - - void - DrawingIsland::CreateUIAProviderForVisual() - { - winrt::com_ptr fragment = m_fragmentFactory->Create(s_colorNames[m_currentColorIndex].c_str(), m_fragmentRoot); - - m_visualToFragmentMap[m_selectedVisual] = fragment; - - // Set up children roots. - m_fragmentRoot->AddChild(fragment); - - // Finally set up parent chain. - fragment->SetParent(m_fragmentRoot); - } - - void - DrawingIsland::Window_Initialize() - { - auto window = m_island.Window(); - - (void)window.StateChanged( - [this](winrt::IContentWindow const&, winrt::IInspectable const&) - { - return Window_StateChanged(); - }); - } - - void - DrawingIsland::Window_StateChanged() - { - bool isLandscapeOrientation = - (m_island.Window().CurrentOrientation() == winrt::ContentDisplayOrientations::Landscape || - m_island.Window().CurrentOrientation() == winrt::ContentDisplayOrientations::LandscapeFlipped); - if (isLandscapeOrientation) - { - m_backgroundBrushDefault = m_compositor.CreateColorBrush(winrt::Colors::DarkOrange()); - m_backgroundVisual.Brush(m_backgroundBrushDefault); - } - else - { - m_backgroundBrushDefault = m_compositor.CreateColorBrush(winrt::Colors::DarkGray()); - m_backgroundVisual.Brush(m_backgroundBrushDefault); - } - } -} diff --git a/Samples/Content/cpp-win32/Squares/DrawingIsland.h b/Samples/Content/cpp-win32/Squares/DrawingIsland.h deleted file mode 100644 index d70b8c920..000000000 --- a/Samples/Content/cpp-win32/Squares/DrawingIsland.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#pragma once - -namespace Squares -{ - class NodeSimpleFragment; - class NodeSimpleFragmentFactory; - class IslandFragmentRoot; - - struct DrawingIsland : - public winrt::implements - { - public: - DrawingIsland( - const winrt::Compositor& compositor); - - ~DrawingIsland(); - - // IClosable methods - void Close(); - - // DrawingIsland methods - winrt::ContentIsland Island() const - { - return m_island; - } - - private: - void Output_Initialize(); - - void Output_AddVisual( - const winrt::float2 point, - bool halfTransparent); - - void Input_Initialize(); - - bool Input_OnKeyDown( - winrt::Windows::System::VirtualKey virtualKey); - - void Input_OnLeftButtonPressed( - const winrt::PointerEventArgs& args); - - void Input_OnPointerMoved( - const winrt::PointerEventArgs& args); - - void Input_OnPointerReleased(); - - void OnLeftClick( - const winrt::float2 point, - bool controlPressed); - - void Accessibility_Initialize(); - - void Accessibility_OnAutomationProviderRequested( - const winrt::ContentIsland& island, - const winrt::ContentIslandAutomationProviderRequestedEventArgs& args); - - void Accessibility_UpdateScreenCoordinates( - winrt::Visual visual); - - void CreateUIAProviderForVisual(); - - void Window_Initialize(); - - void Window_StateChanged(); - - winrt::Visual HitTestVisual( - winrt::float2 const point); - - private: - static inline winrt::Color s_colors[] = - { - { 0xFF, 0x5B, 0x9B, 0xD5 }, - { 0xFF, 0xED, 0x7D, 0x31 }, - { 0xFF, 0x70, 0xAD, 0x47 }, - { 0xFF, 0xFF, 0xC0, 0x00 } - }; - - static inline std::wstring s_colorNames[] = - { - L"Blue", - L"Orange", - L"Green", - L"Yellow" - }; - - winrt::com_ptr m_fragmentFactory{ nullptr }; - winrt::com_ptr m_fragmentRoot{ nullptr }; - winrt::Compositor m_compositor{ nullptr }; - winrt::ContentIsland m_island{ nullptr }; - winrt::InputKeyboardSource m_keyboardSource{ nullptr }; - - // Background - winrt::CompositionColorBrush m_backgroundBrushDefault { nullptr }; - winrt::CompositionColorBrush m_backgroundBrushA { nullptr }; - winrt::CompositionColorBrush m_backgroundBrushB { nullptr }; - winrt::CompositionColorBrush m_backgroundBrushC { nullptr }; - winrt::SpriteVisual m_backgroundVisual { nullptr }; - - // Drawing squares - winrt::VisualCollection m_visuals{ nullptr }; - winrt::Visual m_selectedVisual{ nullptr }; - winrt::SpriteVisual m_currentColorVisual{ nullptr }; - winrt::float2 m_offset{}; - - unsigned int m_currentColorIndex = 0; - winrt::CompositionColorBrush m_colorBrushes[_countof(s_colors)]{ nullptr, nullptr, nullptr, nullptr }; - winrt::CompositionColorBrush m_halfTransparentColorBrushes[_countof(s_colors)]{ nullptr, nullptr, nullptr, nullptr }; - - std::map> m_visualToFragmentMap; - }; -} diff --git a/Samples/Content/cpp-win32/Squares/IslandFragmentRoot.cpp b/Samples/Content/cpp-win32/Squares/IslandFragmentRoot.cpp deleted file mode 100644 index 5fc456268..000000000 --- a/Samples/Content/cpp-win32/Squares/IslandFragmentRoot.cpp +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include "pch.h" - -#include "IslandFragmentRoot.h" -#include "NodeSimpleFragment.h" - -using unique_safearray = wil::unique_any; - -DECLARE_INTERFACE_IID_(IContentIslandAccessibility, IUnknown, "F2DEC451-ABE3-4E84-AAE7-9EAD26F8BD5D") -{ - IFACEMETHOD(GetAutomationHostProvider)( - _COM_Outptr_ IUnknown * *hostProvider - ) PURE; -}; - -namespace Squares -{ - void - IslandFragmentRoot::AddChild( - winrt::com_ptr child) - { - m_children.push_back(child); - } - - std::vector> - IslandFragmentRoot::GetChildren() - { - return m_children; - } - - void - IslandFragmentRoot::SetParent( - winrt::com_ptr parent) - { - m_parent = (parent); - } - - void - IslandFragmentRoot::SetName( - std::wstring name) - { - m_name = std::move(name); - } - - // IRawElementProviderSimple methods - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::get_ProviderOptions( - _Out_ ProviderOptions* retVal) - { - *retVal = (ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading | ProviderOptions_RefuseNonClientSupport); - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::GetPatternProvider( - PATTERNID /* idPattern */, - _Outptr_result_maybenull_ IUnknown** retVal) try - { - *retVal = nullptr; - return S_OK; - } - CATCH_RETURN(); - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::GetPropertyValue( - PROPERTYID idProp, - _Out_ VARIANT* retVal) try - { - ::VariantInit(retVal); - - switch (idProp) - { - case UIA_NamePropertyId: - { - retVal->bstrVal = wil::make_bstr(m_name.c_str()).release(); - retVal->vt = VT_BSTR; - break; - } - - case UIA_IsContentElementPropertyId: - case UIA_IsControlElementPropertyId: - retVal->boolVal = VARIANT_TRUE; - retVal->vt = VT_BOOL; - break; - - case UIA_ControlTypePropertyId: - retVal->vt = VT_I4; - retVal->lVal = UIA_WindowControlTypeId; - break; - } - - return S_OK; - } - CATCH_RETURN(); - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::get_HostRawElementProvider( - _Outptr_ IRawElementProviderSimple** retVal) try - { - *retVal = nullptr; - - auto islandI = m_island.try_as(); - if (islandI) - { - winrt::com_ptr host; - islandI->GetAutomationHostProvider(host.put()); - - *retVal = host.as().detach(); - } - - return S_OK; - } - CATCH_RETURN(); - - winrt::com_ptr - IslandFragmentRoot::GetPreviousSibling() - { - winrt::com_ptr previous = nullptr; - if (m_parent != nullptr) - { - std::vector> siblings = m_parent->GetChildren(); - int index = GetCurrentIndexFromSiblings(siblings); - - if (index != -1) - { - if (index > 0) - { - previous = siblings[index - 1]; - } - } - } - return previous; - } - - winrt::com_ptr - IslandFragmentRoot::GetNextSibling() - { - winrt::com_ptr next = nullptr; - if (m_parent != nullptr) - { - std::vector> siblings = m_parent->GetChildren(); - int index = GetCurrentIndexFromSiblings(siblings); - - if (index != -1) - { - if ((index+1) < static_cast(siblings.size())) - { - next = siblings[index + 1]; - } - } - } - return next; - } - - int - IslandFragmentRoot::GetCurrentIndexFromSiblings( - std::vector> siblings) - { - auto it = find_if( - siblings.begin(), - siblings.end(), - [this](const winrt::com_ptr& v) -> bool { return (v.get() == this); }); - - int index = -1; - if (it != siblings.end()) - { - index = (int)(it - siblings.begin()); - } - - return index; - } - - // IRawElementProviderFragment methods - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::Navigate( - NavigateDirection direction, - _Outptr_result_maybenull_ IRawElementProviderFragment** retVal) - { - direction; - *retVal = nullptr; - - winrt::com_ptr element; - - switch (direction) - { - case NavigateDirection_Parent: - if (m_parent) - { - element = m_parent.as(); - } - break; - - case NavigateDirection_FirstChild: - if (!m_children.empty()) - { - element = m_children.front().as(); - } - break; - - case NavigateDirection_LastChild: - if (!m_children.empty()) - { - element = m_children.back().as(); - } - break; - - case NavigateDirection_NextSibling: - { - winrt::com_ptr nextSibling = GetNextSibling(); - if (nextSibling) - { - element = nextSibling.as(); - } - } - break; - - case NavigateDirection_PreviousSibling: - { - winrt::com_ptr previousSibling = GetPreviousSibling(); - if (previousSibling) - { - element = previousSibling.as(); - } - break; - } - } - - if (element) - { - - *retVal = element.as().detach(); - } - - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::GetRuntimeId( - _Outptr_ SAFEARRAY** retVal) try - { - *retVal = nullptr; - std::array runtimeId = { UiaAppendRuntimeId, 0x1 }; - - unique_safearray runtimeIdArray{ ::SafeArrayCreateVector( - VT_I4, - 0, - static_cast(runtimeId.size())) }; - THROW_HR_IF_NULL(E_FAIL, runtimeIdArray.get()); - for (long i = 0; i < static_cast(runtimeId.size()); ++i) - { - ::SafeArrayPutElement(runtimeIdArray.get(), &i, &runtimeId[i]); - } - - *retVal = runtimeIdArray.release(); - return S_OK; - } - CATCH_RETURN(); - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::get_BoundingRectangle( - _Out_ UiaRect* retVal) - { - *retVal = {}; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::GetEmbeddedFragmentRoots( - _Outptr_result_maybenull_ SAFEARRAY** retVal) - { - *retVal = nullptr; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::SetFocus() - { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::get_FragmentRoot( - _Outptr_ IRawElementProviderFragmentRoot** retVal) - { - *retVal = nullptr; - RETURN_IF_FAILED(QueryInterface(IID_PPV_ARGS(retVal))); - return S_OK; - } - - // IRawElementProviderFragmentRoot methods - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::ElementProviderFromPoint( - double /* x */, - double /* y */, - _Outptr_result_maybenull_ IRawElementProviderFragment** retVal) - { - *retVal = nullptr; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE - IslandFragmentRoot::GetFocus( - _Outptr_result_maybenull_ IRawElementProviderFragment** retVal) - { - *retVal = nullptr; - return S_OK; - } - -} diff --git a/Samples/Content/cpp-win32/Squares/IslandFragmentRoot.h b/Samples/Content/cpp-win32/Squares/IslandFragmentRoot.h deleted file mode 100644 index cc72c9550..000000000 --- a/Samples/Content/cpp-win32/Squares/IslandFragmentRoot.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#pragma once - -namespace Squares -{ - class NodeSimpleFragment; - - class IslandFragmentRoot : - public winrt::implements - { - public: - explicit IslandFragmentRoot( - winrt::ContentIsland island) : m_island(island) {} - - void AddChild( - winrt::com_ptr child); - - std::vector> GetChildren(); - - void SetParent( - winrt::com_ptr parent); - - void SetName( - std::wstring name); - - // IRawElementProviderSimple methods - HRESULT STDMETHODCALLTYPE get_ProviderOptions( - _Out_ ProviderOptions* retVal) override final; - - HRESULT STDMETHODCALLTYPE GetPatternProvider( - PATTERNID /* idPattern */, - _Outptr_result_maybenull_ IUnknown** retVal) override final; - - HRESULT STDMETHODCALLTYPE GetPropertyValue( - PROPERTYID idProp, - _Out_ VARIANT* retVal) override final; - - HRESULT STDMETHODCALLTYPE get_HostRawElementProvider( - _Outptr_ IRawElementProviderSimple** retVal) override final; - - // IRawElementProviderFragment methods - HRESULT STDMETHODCALLTYPE Navigate( - NavigateDirection direction, - _Outptr_result_maybenull_ IRawElementProviderFragment** retVal) override final; - - HRESULT STDMETHODCALLTYPE GetRuntimeId( - _Outptr_ SAFEARRAY** retVal) override final; - - HRESULT STDMETHODCALLTYPE get_BoundingRectangle( - _Out_ UiaRect* retVal) override final; - - HRESULT STDMETHODCALLTYPE GetEmbeddedFragmentRoots( - _Outptr_result_maybenull_ SAFEARRAY** retVal) override final; - - HRESULT STDMETHODCALLTYPE SetFocus() override final; - - HRESULT STDMETHODCALLTYPE get_FragmentRoot( - _Outptr_ IRawElementProviderFragmentRoot** retVal) override final; - - // IRawElementProviderFragmentRoot methods - HRESULT STDMETHODCALLTYPE ElementProviderFromPoint( - double /* x */, - double /* y */, - _Outptr_result_maybenull_ IRawElementProviderFragment** retVal) override final; - - HRESULT STDMETHODCALLTYPE GetFocus( - _Outptr_result_maybenull_ IRawElementProviderFragment** retVal) override final; - - private: - // Helper methods - winrt::com_ptr GetPreviousSibling(); - - winrt::com_ptr GetNextSibling(); - - int GetCurrentIndexFromSiblings( - std::vector> siblings); - - private: - HWND m_hwnd{}; - winrt::ContentIsland m_island{ nullptr }; - std::wstring m_name; - std::vector> m_children; - winrt::com_ptr m_parent; - }; -} diff --git a/Samples/Content/cpp-win32/Squares/NodeSimpleFragment.cpp b/Samples/Content/cpp-win32/Squares/NodeSimpleFragment.cpp deleted file mode 100644 index 01dada93e..000000000 --- a/Samples/Content/cpp-win32/Squares/NodeSimpleFragment.cpp +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include "pch.h" - -#include "IslandFragmentRoot.h" -#include "NodeSimpleFragment.h" - -using unique_safearray = wil::unique_any; - -namespace Squares -{ - NodeSimpleFragment::NodeSimpleFragment( - _In_z_ const wchar_t* name, - int id) : - m_name(name), - m_id(id) - { - } - - void - NodeSimpleFragment::AddChild( - winrt::com_ptr child) - { - m_children.push_back(child); - } - - std::vector> - NodeSimpleFragment::GetChildren() - { - return m_children; - } - - void - NodeSimpleFragment::SetParent( - winrt::com_ptr parent) - { - m_parent = (parent); - } - - void - NodeSimpleFragment::SetBoundingRects( - UiaRect rect) - { - m_boundingRect = rect; - } - - // IRawElementProviderSimple methods - IFACEMETHODIMP - NodeSimpleFragment::get_ProviderOptions( - _Out_ ProviderOptions* retVal) - { - *retVal = (ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading); - return S_OK; - } - - IFACEMETHODIMP - NodeSimpleFragment::GetPatternProvider( - PATTERNID /*patternId*/, - _Outptr_ IUnknown** retVal) try - { - *retVal = nullptr; - return S_OK; - } - CATCH_RETURN(); - - IFACEMETHODIMP - NodeSimpleFragment::GetPropertyValue( - PROPERTYID propertyId, - _Out_ VARIANT* retVal) try - { - ::VariantInit(retVal); - - if (propertyId == UIA_NamePropertyId) - { - retVal->bstrVal = wil::make_bstr(m_name.c_str()).release(); - retVal->vt = VT_BSTR; - } - - return S_OK; - } - CATCH_RETURN(); - - IFACEMETHODIMP - NodeSimpleFragment::get_HostRawElementProvider( - _Outptr_ IRawElementProviderSimple** retVal) - { - *retVal = nullptr; - return S_OK; - } - - winrt::com_ptr - NodeSimpleFragment::GetPreviousSibling() - { - winrt::com_ptr previous = nullptr; - if (m_parent != nullptr) - { - std::vector> siblings = m_parent->GetChildren(); - int index = GetCurrentIndexFromSiblings(siblings); - - if (index != -1) - { - if (index > 0) - { - previous = siblings[index - 1]; - } - } - } - return previous; - } - - winrt::com_ptr - NodeSimpleFragment::GetNextSibling() - { - winrt::com_ptr next = nullptr; - if (m_parent != nullptr) - { - std::vector> siblings = m_parent->GetChildren(); - int index = GetCurrentIndexFromSiblings(siblings); - - if (index != -1) - { - if ((index + 1) < static_cast(siblings.size())) - { - next = siblings[index + 1]; - } - } - } - return next; - } - - int - NodeSimpleFragment::GetCurrentIndexFromSiblings( - std::vector> siblings) - { - auto it = std::find_if( - siblings.begin(), - siblings.end(), - [this](const winrt::com_ptr& v) -> bool { return (v.get() == this); }); - - int index = -1; - if (it != siblings.end()) - { - index = (int)(it - siblings.begin()); - } - - return index; - } - - // IRawElementProviderFragment methods - IFACEMETHODIMP - NodeSimpleFragment::Navigate( - _In_ NavigateDirection direction, - _Outptr_ IRawElementProviderFragment** retVal) try - { - *retVal = nullptr; - - winrt::com_ptr result; - switch (direction) - { - case NavigateDirection_Parent: - if (m_parent) - { - result = m_parent.as(); - } - break; - - case NavigateDirection_FirstChild: - if (!m_children.empty()) - { - result = m_children.front().as(); - } - break; - - case NavigateDirection_LastChild: - if (!m_children.empty()) - { - result = m_children.back().as(); - } - break; - - case NavigateDirection_NextSibling: - { - winrt::com_ptr nextSibling = GetNextSibling(); - if (nextSibling) - { - result = nextSibling.as(); - } - } - break; - - case NavigateDirection_PreviousSibling: - { - winrt::com_ptr previousSibling = GetPreviousSibling(); - if (previousSibling) - { - result = previousSibling.as(); - } - } - break; - - } - - *retVal = result.detach(); - return S_OK; - } - CATCH_RETURN(); - - IFACEMETHODIMP - NodeSimpleFragment::GetRuntimeId( - _Outptr_ SAFEARRAY** retVal) - { - *retVal = nullptr; - - std::array runtimeId = { UiaAppendRuntimeId, m_id }; - - unique_safearray runtimeIdArray{ ::SafeArrayCreateVector( - VT_I4, - 0, - static_cast(runtimeId.size())) }; - THROW_HR_IF_NULL(E_FAIL, runtimeIdArray.get()); - for (long i = 0; i < static_cast(runtimeId.size()); ++i) - { - ::SafeArrayPutElement(runtimeIdArray.get(), &i, &runtimeId[i]); - } - - *retVal = runtimeIdArray.release(); - return S_OK; - } - - IFACEMETHODIMP - NodeSimpleFragment::get_BoundingRectangle( - _Out_ UiaRect* retVal) - { - *retVal = m_boundingRect; - return S_OK; - } - - IFACEMETHODIMP - NodeSimpleFragment::GetEmbeddedFragmentRoots( - _Outptr_ SAFEARRAY** retVal) - { - *retVal = nullptr; - return S_OK; - } - - IFACEMETHODIMP - NodeSimpleFragment::SetFocus() - { - return S_OK; - } - - IFACEMETHODIMP - NodeSimpleFragment::get_FragmentRoot( - _Outptr_ IRawElementProviderFragmentRoot** retVal) try - { - if (m_parent) - { - winrt::com_ptr result = m_parent.as(); - *retVal = result.detach(); - } - - return S_OK; - } - CATCH_RETURN(); - -} diff --git a/Samples/Content/cpp-win32/Squares/NodeSimpleFragment.h b/Samples/Content/cpp-win32/Squares/NodeSimpleFragment.h deleted file mode 100644 index 2e47f5cb4..000000000 --- a/Samples/Content/cpp-win32/Squares/NodeSimpleFragment.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#pragma once - -namespace Squares -{ - class IslandFragmentRoot; - - class NodeSimpleFragment : - public winrt::implements - { - public: - NodeSimpleFragment( - _In_z_ const wchar_t* name, - int id); - - void AddChild(winrt::com_ptr child); - - std::vector> GetChildren(); - - void SetId( - int id); - - void SetBoundingRects( - UiaRect rect); - - void SetName( - std::wstring name); - - void SetParent( - winrt::com_ptr parent); - - // IRawElementProviderSimple methods - IFACEMETHODIMP get_ProviderOptions( - _Out_ ProviderOptions* retVal) override final; - - IFACEMETHODIMP GetPatternProvider( - PATTERNID patternId, - _Outptr_ IUnknown** retVal) override final; - - IFACEMETHODIMP GetPropertyValue( - PROPERTYID propertyId, - _Out_ VARIANT* retVal) override final; - - IFACEMETHODIMP get_HostRawElementProvider( - _Outptr_ IRawElementProviderSimple** retVal) override final; - - // IRawElementProviderFragment methods - IFACEMETHODIMP Navigate( - _In_ NavigateDirection direction, - _Outptr_ IRawElementProviderFragment** retVal) override final; - - IFACEMETHODIMP GetRuntimeId( - _Outptr_ SAFEARRAY** retVal) override final; - - IFACEMETHODIMP get_BoundingRectangle( - _Out_ UiaRect* retVal) override final; - - IFACEMETHODIMP GetEmbeddedFragmentRoots( - _Outptr_ SAFEARRAY** retVal) override final; - - IFACEMETHODIMP SetFocus(); - - IFACEMETHODIMP get_FragmentRoot( - _Outptr_ IRawElementProviderFragmentRoot** retVal) override final; - - private: - // Helper methods - // For the below 3 methods create a generic function instead so that they can be reused. - winrt::com_ptr GetPreviousSibling(); - - winrt::com_ptr GetNextSibling(); - - int GetCurrentIndexFromSiblings( - std::vector> siblings); - - private: - winrt::com_ptr m_parent; - std::vector> m_children; - - int m_id = 0xff; - std::wstring m_name; - UiaRect m_boundingRect = { 0, 0, 0, 0 }; - }; - - // A helper class that creates Fragments that are part of the same hierarchy. Most importantly, - // it ensures that each NodeSimpleFragment gets assigned a unique ID. - class NodeSimpleFragmentFactory: - public winrt::implements - { - public: - winrt::com_ptr Create( - _In_z_ const wchar_t* name, - winrt::com_ptr fragmentRoot) - { - return winrt::make_self(name, ++m_nextId); - } - - private: - int m_nextId = 10; - }; -} diff --git a/Samples/Content/cpp-win32/Squares/Squares.sln b/Samples/Content/cpp-win32/Squares/Squares.sln deleted file mode 100644 index 74f404b86..000000000 --- a/Samples/Content/cpp-win32/Squares/Squares.sln +++ /dev/null @@ -1,37 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32630.194 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Squares", "Squares.vcxproj", "{BF13F903-0EA5-4B58-8631-7DB2C0E60734}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Debug|ARM64.Build.0 = Debug|ARM64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Debug|x64.ActiveCfg = Debug|x64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Debug|x64.Build.0 = Debug|x64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Debug|x86.ActiveCfg = Debug|Win32 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Debug|x86.Build.0 = Debug|Win32 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Release|ARM64.ActiveCfg = Release|ARM64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Release|ARM64.Build.0 = Release|ARM64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Release|x64.ActiveCfg = Release|x64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Release|x64.Build.0 = Release|x64 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Release|x86.ActiveCfg = Release|Win32 - {BF13F903-0EA5-4B58-8631-7DB2C0E60734}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {CF5B744B-97DE-434B-9CF3-602BC02A1968} - EndGlobalSection -EndGlobal diff --git a/Samples/Content/cpp-win32/Squares/Squares.vcxproj b/Samples/Content/cpp-win32/Squares/Squares.vcxproj deleted file mode 100644 index 77a78fcc1..000000000 --- a/Samples/Content/cpp-win32/Squares/Squares.vcxproj +++ /dev/null @@ -1,261 +0,0 @@ - - - - - packages - - - - - - - - Debug - ARM64 - - - Debug - Win32 - - - Release - ARM64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {BF13F903-0EA5-4B58-8631-7DB2C0E60734} - Squares - 10.0 - - None - false - False - high - - - - Application - true - Unicode - - - Application - false - true - Unicode - - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - true - - - false - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - Create - pch.h - - - Windows - true - - - - - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Windows - true - - - - - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Windows - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - \ No newline at end of file diff --git a/Samples/Content/cpp-win32/Squares/WinMain.cpp b/Samples/Content/cpp-win32/Squares/WinMain.cpp deleted file mode 100644 index 18dbb9a10..000000000 --- a/Samples/Content/cpp-win32/Squares/WinMain.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include "pch.h" - -#include "DrawingIsland.h" - - -int __stdcall WinMain( - _In_ HINSTANCE, - _In_opt_ HINSTANCE, - _In_ PSTR, - _In_ int) -{ - // This application is referencing WindowsAppSDK using the unpackaged sceanario - // by setting None in the project file. - // https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/deploy-unpackaged-apps - - // Initialize current thread for COM/WinRT. - winrt::init_apartment(winrt::apartment_type::single_threaded); - - // Create a Lifted (WinAppSDK) DispatcherQueue for this thread. This is needed for - // Microsoft.UI.Composition, Content, and Input APIs. - auto dispatcherQueueController = - winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread(); - - auto dispatcherQueue = dispatcherQueueController.DispatcherQueue(); - - // Create a top level AppWindow and show it. - auto appWindow = winrt::AppWindow::Create(); - appWindow.Title(L"Squares"); - appWindow.Show(); - - // When the AppWindow is closing, post a quit to the message loop so we return from WinMain. - auto destroyingEventToken = appWindow.Destroying( - [&](winrt::AppWindow const& /*sender*/, - winrt::IInspectable const& /*args*/) - { - dispatcherQueue.EnqueueEventLoopExit(); - }); - - // Create a Compositor for all Content on this thread. - auto compositor = winrt::Microsoft::UI::Composition::Compositor(); - - // Create a DesktopChildSiteBridge that allows Content to be hosted in a HWND environment. - auto desktopChildSiteBridge = winrt::DesktopChildSiteBridge::Create(compositor, appWindow.Id()); - - // Make the DesktopChildSiteBridge visible. - desktopChildSiteBridge.Show(); - - // Set the resize policy so the DesktopChildSiteBridge matches its parent HWND size. - desktopChildSiteBridge.ResizePolicy(winrt::ContentSizePolicy::ResizeContentToParentWindow); - - // Create a DrawingIsland that uses a ContentIsland to provide Output, Input, - // Layout and Accesiblity functionality. - winrt::com_ptr drawingIsland = - winrt::make_self(compositor); - - // Connect the DesktopChildSiteBridge with the ContentIsland. - desktopChildSiteBridge.Connect(drawingIsland->Island()); - - // Run the event loop until somebody posts a quit message. - dispatcherQueue.RunEventLoop(); - - appWindow.Destroying(destroyingEventToken); - - dispatcherQueueController.ShutdownQueue(); - - return 0; -} diff --git a/Samples/Content/cpp-win32/Squares/packages.config b/Samples/Content/cpp-win32/Squares/packages.config deleted file mode 100644 index 8968b7311..000000000 --- a/Samples/Content/cpp-win32/Squares/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Samples/Content/cpp-win32/Squares/readme.md b/Samples/Content/cpp-win32/Squares/readme.md deleted file mode 100644 index 6488d9df7..000000000 --- a/Samples/Content/cpp-win32/Squares/readme.md +++ /dev/null @@ -1,44 +0,0 @@ -# Squares sample - -This sample illustrates how to use the Input, Composition, Accessibility and Content APIs to create -an interactive user experience. - -## Building & Running the sample - -This sample uses experimental API's first published in WindowsAppSdk 1.2 Experimental release. -You should just be able to build the sample in Visual Studio by opening Squares.sln. -Since this is an unpackaged application, WindowsAppSdk 1.2 Experimental Runtime will need to be -installed manually before running the sample. - -Here are the links for the installer packages for WindowsAppSdk 1.2 Experimental Runtime: - -- [AMD64](https://aka.ms/windowsappsdk/1.2/1.2.220909.2-experimental2/windowsappruntimeinstall-x64.exe) -- [ARM64](https://aka.ms/windowsappsdk/1.2/1.2.220909.2-experimental2/windowsappruntimeinstall-arm64.exe) -- [X86](https://aka.ms/windowsappsdk/1.2/1.2.220909.2-experimental2/windowsappruntimeinstall-x86.exe) - - -## Conceptual elements - -### Host - -The host is represented by the `DesktopChildSiteBridge`, and allows hosting in a HWND based -environment. It takes a parent HWND as a parameter on creation, and it will be a child of that -parent HWND. - - -### Content - -The content is represented by the `ContentIsland` and is a self-contained set of output, input, -state, and automation handling that provides a user experience. An application typically uses -`ContentIslands` as modernized [WS_CHILD -style HWND](https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#child-windows) -equivalents to provide Composition-based experiences with animations, rendering effects, and -interactive manipulations. - -## Connection - -After `DesktopChildSiteBridge` and `ContentIsland` are created, they need to be connected so that -the Content will show up in the Host. This is accomplished by calling -DesktopChildSiteBridge.Connect(ContentIsland). Once this connection has been established, the -Content will inherit state from the HWND environment around it by default. For instance, if the -parent HWND is hidden or resized, the Content will also follow that state. diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.exe.manifest b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.exe.manifest new file mode 100644 index 000000000..ac71f191f --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.exe.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + + diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.rc b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.rc new file mode 100644 index 000000000..6d2853291 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.rc differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj new file mode 100644 index 000000000..3643e885c --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj @@ -0,0 +1,149 @@ + + + + + + + true + true + true + true + 15.0 + {74605fc4-2e57-459f-947b-aef9f6921ae8} + Win32Proj + DrawingCppTestApp + 10.0.22621.0 + 10.0.18362.0 + DrawingCppTestApp + + + + + Debug + ARM64 + + + Debug + Win32 + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + Application + v143 + v142 + v141 + v140 + Unicode + + + true + true + + + false + true + false + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + _CONSOLE;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + Level4 + %(AdditionalOptions) /permissive- /bigobj + + + Windows + false + + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + + MaxSpeed + true + true + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + + + Create + + + + + + + false + + + + + {709c54e1-0f2f-4a59-80b2-4cfd08b720e5} + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj.filters b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj.filters new file mode 100644 index 000000000..1e99aa07e --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj.filters @@ -0,0 +1,48 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + + + + + + + + + + + + + Resource Files + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/PropertySheet.props b/Samples/Islands/DrawingIsland/DrawingCppTestApp/PropertySheet.props new file mode 100644 index 000000000..e34141b01 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/WinMain.cpp b/Samples/Islands/DrawingIsland/DrawingCppTestApp/WinMain.cpp new file mode 100644 index 000000000..3100b52e1 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/WinMain.cpp @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" + +int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) +{ + winrt::init_apartment(winrt::apartment_type::single_threaded); + + auto controller{ winrt::DispatcherQueueController::CreateOnCurrentThread() }; + auto queue = controller.DispatcherQueue(); + + // Associate the AppWindow's lifetime with the DispatcherQueue to automatically close on exit. + auto window = winrt::AppWindow::Create(); + window.AssociateWithDispatcherQueue(queue); + window.Closing( + [queue](auto&&, auto&&) + { + // Ensure the DispatcherQueue exits the event loop on close. + queue.EnqueueEventLoopExit(); + }); + + window.Title(L"Drawing C++ TestApp"); + window.Show(); + +#pragma region ... + // Create a ContentSiteBridge and connect Island content into it. + auto compositor = winrt::Compositor(); + auto siteBridge = winrt::DesktopChildSiteBridge::Create(compositor, window.Id()); + siteBridge.ResizePolicy(winrt::ContentSizePolicy::ResizeContentToParentWindow); + siteBridge.Show(); + + auto island = winrt::DrawingIsland(compositor).Island(); + siteBridge.Connect(island); + + // Move initial focus to the ContentIsland. + auto focusNavigationHost = winrt::InputFocusNavigationHost::GetForSiteBridge(siteBridge); + focusNavigationHost.NavigateFocus(winrt::FocusNavigationRequest::Create( + winrt::FocusNavigationReason::Programmatic)); +#pragma endregion + + queue.RunEventLoop(); + + controller.ShutdownQueue(); +} diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/packages.config b/Samples/Islands/DrawingIsland/DrawingCppTestApp/packages.config new file mode 100644 index 000000000..02e8fb621 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Samples/Content/cpp-win32/Squares/pch.cpp b/Samples/Islands/DrawingIsland/DrawingCppTestApp/pch.cpp similarity index 100% rename from Samples/Content/cpp-win32/Squares/pch.cpp rename to Samples/Islands/DrawingIsland/DrawingCppTestApp/pch.cpp diff --git a/Samples/Content/cpp-win32/Squares/pch.h b/Samples/Islands/DrawingIsland/DrawingCppTestApp/pch.h similarity index 53% rename from Samples/Content/cpp-win32/Squares/pch.h rename to Samples/Islands/DrawingIsland/DrawingCppTestApp/pch.h index 883dded31..6ec4e8770 100644 --- a/Samples/Content/cpp-win32/Squares/pch.h +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/pch.h @@ -3,40 +3,30 @@ #pragma once -#include -#include -#include -#include - -#include +#include +#ifdef GetCurrentTime +#undef GetCurrentTime +#endif #include -#include "winrt/Windows.Foundation.Collections.h" +#include #include -#include +#include #include #include #include #include #include -// UIA automation related headers -#include -#include -#include +#include "winrt/DrawingIslandComponents.h" namespace winrt { - using namespace Windows::Foundation; - using namespace Windows::Foundation::Collections; - using namespace Windows::Foundation::Numerics; - using namespace Windows::System; - using namespace Windows::UI; - using namespace Microsoft::UI::Composition; using namespace Microsoft::UI::Content; using namespace Microsoft::UI::Dispatching; using namespace Microsoft::UI::Input; using namespace Microsoft::UI::Windowing; -} + using namespace DrawingIslandComponents; +} diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/readme.txt b/Samples/Islands/DrawingIsland/DrawingCppTestApp/readme.txt new file mode 100644 index 000000000..e0e905805 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/readme.txt @@ -0,0 +1,30 @@ +======================================================================== + C++/WinRT DrawingIsland Project Overview +======================================================================== + +This project demonstrates how to get started consuming Windows Runtime +classes directly from standard C++, using platform projection headers +generated from Windows SDK metadata files. + +Steps to generate and consume SDK platform projection: +1. Build project initially to generate platform projection headers into + your Generated Files folder. +2. Include a projection namespace header in your pch.h, such as + . +3. Consume winrt namespace and any Windows Runtime namespaces, such as + winrt::Windows::Foundation, from source code. +4. Initialize apartment via init_apartment() and consume winrt classes. + +Steps to generate and consume a projection from third party metadata: +1. Add a WinMD reference by right-clicking the References project node + and selecting "Add Reference...". In the Add References dialog, + browse to the component WinMD you want to consume and add it. +2. Build the project once to generate projection headers for the + referenced WinMD file under the "Generated Files" subfolder. +3. As above, include projection headers in pch or source code + to consume projected Windows Runtime classes. + +======================================================================== +Learn more about C++/WinRT here: +http://aka.ms/cppwinrt/ +======================================================================== diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/resource.h b/Samples/Islands/DrawingIsland/DrawingCppTestApp/resource.h new file mode 100644 index 000000000..5b37dd6a2 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/resource.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/DrawingCppTestPackage.wapproj b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/DrawingCppTestPackage.wapproj new file mode 100644 index 000000000..b1aed5c10 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/DrawingCppTestPackage.wapproj @@ -0,0 +1,67 @@ + + + + 15.0 + + + + Debug + x86 + + + Release + x86 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\ + + + + 3099b355-5306-4814-bc1c-08ab3f29b32e + 10.0.22621.0 + 10.0.17763.0 + en-US + false + $(NoWarn);NU1702 + ..\DrawingCppTestApp\DrawingCppTestApp.vcxproj + + + + Designer + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/LockScreenLogo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/LockScreenLogo.scale-200.png new file mode 100644 index 000000000..735f57adb Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/LockScreenLogo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/SplashScreen.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/SplashScreen.scale-200.png new file mode 100644 index 000000000..023e7f1fe Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/SplashScreen.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square150x150Logo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square150x150Logo.scale-200.png new file mode 100644 index 000000000..af49fec1a Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square150x150Logo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square44x44Logo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square44x44Logo.scale-200.png new file mode 100644 index 000000000..ce342a2ec Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square44x44Logo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 000000000..f6c02ce97 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/StoreLogo.png b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/StoreLogo.png new file mode 100644 index 000000000..7385b56c0 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/StoreLogo.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Wide310x150Logo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Wide310x150Logo.scale-200.png new file mode 100644 index 000000000..288995b39 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Images/Wide310x150Logo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Package.appxmanifest b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Package.appxmanifest new file mode 100644 index 000000000..030dc6399 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCppTestPackage/Package.appxmanifest @@ -0,0 +1,48 @@ + + + + + + + + DrawingCppTestApp + Microsoft Corporation (jstall) + Images\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/LottieLogo1.json b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/LottieLogo1.json new file mode 100644 index 000000000..cb637e3ea --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/LottieLogo1.json @@ -0,0 +1,7390 @@ +{ + "assets": [], + "layers": [ + { + "ddd": 0, + "ind": 0, + "ty": 1, + "nm": "MASTER", + "ks": { + "o": { "k": 0 }, + "r": { "k": 0 }, + "p": { "k": [ 214.457, 347.822, 0 ] }, + "a": { "k": [ 60, 60, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "sw": 120, + "sh": 120, + "sc": "#ffffff", + "ip": 12, + "op": 179, + "st": 0, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "S5-Y 4", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": -89.1 }, + "p": { "k": [ 53.205, 131.606, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 142.038, 29.278 ], + [ 131.282, 21.807 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 76, + "s": [ 87 ], + "e": [ 50.633 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 79, + "s": [ 50.633 ], + "e": [ 0 ] + }, + { "t": 83 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 76, + "s": [ 100 ], + "e": [ 75.856 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 79, + "s": [ 75.856 ], + "e": [ 0 ] + }, + { "t": 83 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 76, + "op": 84, + "st": 40, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 2, + "ty": 4, + "nm": "S4-Y 4", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": -89.1 }, + "p": { "k": [ 53.205, 131.606, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 142.183, -5.112 ], + [ 130.029, 5.016 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 76, + "s": [ 87 ], + "e": [ 43.833 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 79, + "s": [ 43.833 ], + "e": [ 0 ] + }, + { "t": 83 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 76, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 79, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 83 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 76, + "op": 84, + "st": 40, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 3, + "ty": 4, + "nm": "S3-Y 4", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": -89.1 }, + "p": { "k": [ 53.205, 131.606, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 147.699, 13.025 ], + [ 133.195, 13.21 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 76, + "s": [ 87 ], + "e": [ 42.133 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 79, + "s": [ 42.133 ], + "e": [ 0 ] + }, + { "t": 83 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 76, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 79, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 83 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 76, + "op": 84, + "st": 40, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 4, + "ty": 4, + "nm": "S5-Y 3", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 97.9 }, + "p": { "k": [ 58.205, -39.394, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 145.677, 22.22 ], + [ 134.922, 14.749 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 75, + "s": [ 87 ], + "e": [ 50.633 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 78, + "s": [ 50.633 ], + "e": [ 0 ] + }, + { "t": 82 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 75, + "s": [ 100 ], + "e": [ 75.856 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 78, + "s": [ 75.856 ], + "e": [ 0 ] + }, + { "t": 82 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 75, + "op": 83, + "st": 39, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 5, + "ty": 4, + "nm": "S4-Y 3", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 97.9 }, + "p": { "k": [ 58.205, -39.394, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 144.429, -5.397 ], + [ 132.275, 4.731 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 75, + "s": [ 87 ], + "e": [ 43.833 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 78, + "s": [ 43.833 ], + "e": [ 0 ] + }, + { "t": 82 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 75, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 78, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 82 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 75, + "op": 83, + "st": 39, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 6, + "ty": 4, + "nm": "S3-Y 3", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 97.9 }, + "p": { "k": [ 58.205, -39.394, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 149.624, 8.244 ], + [ 136.648, 10.156 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 75, + "s": [ 87 ], + "e": [ 42.133 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 78, + "s": [ 42.133 ], + "e": [ 0 ] + }, + { "t": 82 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 75, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 78, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 82 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 75, + "op": 83, + "st": 39, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 7, + "ty": 4, + "nm": "S13", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 128, 3.65 ], + [ 78.25, 3.5 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 85, + "s": [ 87 ], + "e": [ 21.233 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 90, + "s": [ 21.233 ], + "e": [ 0 ] + }, + { "t": 94 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 85, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 90, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 94 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 1.5 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 85, + "op": 95, + "st": 49, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 8, + "ty": 4, + "nm": "S12", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 119.25, -20.05 ], + [ 63.5, -20.5 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 84, + "s": [ 87 ], + "e": [ 21.233 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 87, + "s": [ 21.233 ], + "e": [ 0 ] + }, + { "t": 91 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 84, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 87, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 91 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 1.5 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 84, + "op": 94, + "st": 48, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 9, + "ty": 4, + "nm": "S11", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 119.5, -45.05 ], + [ 82.75, -44.75 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 80, + "s": [ 87 ], + "e": [ 21.233 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 83, + "s": [ 21.233 ], + "e": [ 0 ] + }, + { "t": 87 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 80, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 83, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 87 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 1.5 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 80, + "op": 90, + "st": 44, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 10, + "ty": 4, + "nm": "S5-Y 2", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 169.5, 18.073 ], + [ 137.481, 11.365 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 97, + "s": [ 87 ], + "e": [ 50.633 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 100, + "s": [ 50.633 ], + "e": [ 0 ] + }, + { "t": 107 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 97, + "s": [ 100 ], + "e": [ 75.856 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 100, + "s": [ 75.856 ], + "e": [ 0 ] + }, + { "t": 107 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 97, + "op": 107, + "st": 61, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 11, + "ty": 4, + "nm": "S4-Y 2", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 156.45, -23.05 ], + [ 132, 2.75 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 97, + "s": [ 87 ], + "e": [ 43.833 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 100, + "s": [ 43.833 ], + "e": [ 0 ] + }, + { "t": 107 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 97, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 100, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 107 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 97, + "op": 107, + "st": 61, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 12, + "ty": 4, + "nm": "S3-Y 2", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 166.731, -7.927 ], + [ 136.731, 7.115 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 97, + "s": [ 87 ], + "e": [ 42.133 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 100, + "s": [ 42.133 ], + "e": [ 0 ] + }, + { "t": 107 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 97, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 100, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 107 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 97, + "op": 107, + "st": 61, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 13, + "ty": 4, + "nm": "S6-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -87.5, 20.95 ], + [ -48.75, 54.75 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 87 ], + "e": [ 43.933 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 43.933 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 100 ], + "e": [ 70.456 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 70.456 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 54, + "op": 64, + "st": 18, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 14, + "ty": 4, + "nm": "S5-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -94.5, 37.073 ], + [ -48.769, 55.365 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 87 ], + "e": [ 50.633 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 50.633 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 100 ], + "e": [ 75.856 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 75.856 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 54, + "op": 64, + "st": 18, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 15, + "ty": 4, + "nm": "S4-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 7.45, 21.95 ], + [ -32.75, 55.75 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 87 ], + "e": [ 43.833 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 43.833 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 54, + "op": 64, + "st": 18, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 16, + "ty": 4, + "nm": "S3-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 16.231, 39.073 ], + [ -32.769, 57.365 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 87 ], + "e": [ 42.133 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 42.133 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 57, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 64 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 2 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 54, + "op": 64, + "st": 18, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 17, + "ty": 4, + "nm": "S8", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ -0.148, 14.256 ], + [ 10.476, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ -8.551, -8.263 ], + [ -21.454, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -3, 35.95 ], + [ -1.352, -6.756 ], + [ -32.046, -20.579 ], + [ -42.25, 4.25 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 65, + "s": [ 87 ], + "e": [ 21.233 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 70, + "s": [ 21.233 ], + "e": [ 0 ] + }, + { "t": 75 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 65, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 70, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 75 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 1.5 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 65, + "op": 75, + "st": 29, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 18, + "ty": 4, + "nm": "S7", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 27, 1.45 ], + [ 31.046, -1.421 ], + [ 0, 0 ] + ], + "o": [ + [ -27, -1.45 ], + [ -26.426, 1.21 ], + [ 0, 0 ] + ], + "v": [ + [ 34.5, -13.05 ], + [ -35.046, -35.579 ], + [ -62.25, -5.75 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 65, + "s": [ 87 ], + "e": [ 21.233 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 70, + "s": [ 21.233 ], + "e": [ 0 ] + }, + { "t": 75 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 65, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 70, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 75 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 1.5 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 65, + "op": 75, + "st": 29, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 19, + "ty": 4, + "nm": "S2-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 1.9, -10.768 ], + [ 1, -19 ] + ], + "o": [ + [ 0, 0 ], + [ -3.167, 17.951 ], + [ -1, 19 ] + ], + "v": [ + [ -67.25, -105.5 ], + [ -72.333, -84.201 ], + [ -76.5, -37.75 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 29, + "s": [ 87 ], + "e": [ 25.333 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 33, + "s": [ 25.333 ], + "e": [ 0 ] + }, + { "t": 36 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 29, + "s": [ 100 ], + "e": [ 69.056 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 33, + "s": [ 69.056 ], + "e": [ 0 ] + }, + { "t": 36 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 1.5 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 30, + "op": 37, + "st": -7, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 20, + "ty": 4, + "nm": "S1-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 25.043, 45.678, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 1.9, -10.768 ], + [ 1, -19 ] + ], + "o": [ + [ 0, 0 ], + [ -3.167, 17.951 ], + [ -1, 19 ] + ], + "v": [ + [ -67.125, -112 ], + [ -75.458, -89.951 ], + [ -80.375, -39.25 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 29, + "s": [ 87 ], + "e": [ 37.533 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 33, + "s": [ 37.533 ], + "e": [ 0 ] + }, + { "t": 36 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 29, + "s": [ 100 ], + "e": [ 66.356 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 33, + "s": [ 66.356 ], + "e": [ 0 ] + }, + { "t": 36 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 1.5 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Shape 1" + } + ], + "ip": 30, + "op": 37, + "st": -7, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 21, + "ty": 4, + "nm": "Dot1", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.823, + "y": 0 + }, + "n": "0p833_0p833_0p823_0", + "t": -3, + "s": [ 295.771, 108.994, 0 ], + "e": [ 35.771, 108.994, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 16 } + ] + }, + "a": { "k": [ 196.791, 266.504, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { "k": [ 9.4, 9.4 ] }, + "p": { "k": [ 0.8, -0.5 ] }, + "nm": "Ellipse Path 1" + }, + { + "ty": "fl", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "nm": "Fill 1" + }, + { + "ty": "tr", + "p": { + "k": [ 196, 267 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1" + } + ], + "ip": -5, + "op": 17, + "st": -36, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 22, + "ty": 4, + "nm": "L-B", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 25.671, -4.167 ], + [ 1.456, 6.902 ], + [ -8.481, 1.863 ], + [ -47.562, 13.01 ], + [ -0.501, 0.133 ], + [ -71.423, -2.315 ] + ], + "o": [ + [ 0, 0 ], + [ -8.224, 1.335 ], + [ -1.456, -6.903 ], + [ 23.817, -5.233 ], + [ 0.16, -0.044 ], + [ 0.501, -0.133 ], + [ 0, 0 ] + ], + "v": [ + [ -8.837, -58.229 ], + [ -35.834, 33.662 ], + [ -51.688, 23.148 ], + [ -41.174, 7.293 ], + [ 51.797, 44.178 ], + [ 53.188, 43.741 ], + [ 140.394, 43.672 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 166.029, 270.643 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 8" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.703 ], + "y": [ 0.821 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p703_0p821_0p167_0p167" ], + "t": 18, + "s": [ 80 ], + "e": [ 50 ] + }, + { + "i": { + "x": [ 0.263 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.037 ], + "y": [ 0.168 ] + }, + "n": [ "0p263_1_0p037_0p168" ], + "t": 23, + "s": [ 50 ], + "e": [ 30 ] + }, + { "t": 55 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.337 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p337_1_0p167_0p167" ], + "t": 18, + "s": [ 81 ], + "e": [ 73.4 ] + }, + { "t": 29 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + } + ], + "ip": 18, + "op": 179, + "st": 8, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 23, + "ty": 4, + "nm": "L-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 25.671, -4.167 ], + [ 1.456, 6.902 ], + [ -8.481, 1.863 ], + [ -47.562, 13.01 ], + [ -0.501, 0.133 ], + [ -71.423, -2.315 ] + ], + "o": [ + [ 0, 0 ], + [ -8.224, 1.335 ], + [ -1.456, -6.903 ], + [ 23.817, -5.233 ], + [ 0.16, -0.044 ], + [ 0.501, -0.133 ], + [ 0, 0 ] + ], + "v": [ + [ -8.837, -58.229 ], + [ -35.834, 33.662 ], + [ -51.688, 23.148 ], + [ -41.174, 7.293 ], + [ 51.797, 44.178 ], + [ 53.188, 43.741 ], + [ 140.394, 43.672 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.4 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 166.029, 270.643 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 8" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.703 ], + "y": [ 0.857 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p703_0p857_0p167_0p167" ], + "t": 16, + "s": [ 80 ], + "e": [ 50 ] + }, + { + "i": { + "x": [ 0.938 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.333 ], + "y": [ 0.202 ] + }, + "n": [ "0p938_1_0p333_0p202" ], + "t": 20, + "s": [ 50 ], + "e": [ 0 ] + }, + { "t": 28 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.337 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p337_1_0p167_0p167" ], + "t": 16, + "s": [ 81 ], + "e": [ 73.4 ] + }, + { "t": 27 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + } + ], + "ip": 16, + "op": 179, + "st": 8, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 24, + "ty": 1, + "nm": "N", + "parent": 0, + "ks": { + "o": { "k": 0 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.26, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p26_1_0p167_0p167", + "t": 28, + "s": [ -33.667, 8.182, 0 ], + "e": [ -33.667, -72.818, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.74, + "y": 0 + }, + "n": "0p833_0p833_0p74_0", + "t": 40, + "s": [ -33.667, -72.818, 0 ], + "e": [ -33.667, 102.057, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 54 } + ] + }, + "a": { "k": [ 60, 60, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "sw": 120, + "sh": 120, + "sc": "#ffffff", + "ip": 28, + "op": 54, + "st": 0, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 25, + "ty": 4, + "nm": "Dot-Y", + "parent": 24, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p833_0p833_0p167_0p167", + "t": 28, + "s": [ 39.875, 60, 0 ], + "e": [ 79.375, 60, 0 ], + "to": [ 6.58333349227905, 0, 0 ], + "ti": [ -6.58333349227905, 0, 0 ] + }, + { "t": 54 } + ] + }, + "a": { "k": [ 196.791, 266.504, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { "k": [ 9.4, 9.4 ] }, + "p": { "k": [ 0.8, -0.5 ] }, + "nm": "Ellipse Path 1" + }, + { + "ty": "fl", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "nm": "Fill 1" + }, + { + "ty": "tr", + "p": { + "k": [ 196, 267 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1" + } + ], + "ip": 28, + "op": 54, + "st": 4, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 26, + "ty": 4, + "nm": "T1a-B", + "parent": 36, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 250, 250, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ -0.5, 9.501 ], + [ -0.048, 5.655 ], + [ 0.054, 0.06 ], + [ 0.946, 1.486 ], + [ -9.967, 8.05 ], + [ -40.546, 0 ] + ], + "o": [ + [ 0.031, -0.594 ], + [ 0.076, -8.978 ], + [ -1.161, -1.3 ], + [ -5.939, -9.327 ], + [ 24.677, -19.929 ], + [ 0, 0 ] + ], + "v": [ + [ -30.72, 63.761 ], + [ -30.741, 45.192 ], + [ -37.397, 27.014 ], + [ -40.698, 22.661 ], + [ -37.873, -7.117 ], + [ 49.506, 11.559 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": 24.9, + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.673 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p673_1_0p167_0p167" ], + "t": 70, + "s": [ 24.9 ], + "e": [ 89.1 ] + }, + { "t": 84 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 227.677, 234.375 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 9" + } + ], + "ip": 70, + "op": 179, + "st": 17, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 27, + "ty": 4, + "nm": "T2a-B", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 1.681, -29.992 ], + [ -1.681, 29.992 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.06 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p06_1_0p167_0p167" ], + "t": 75, + "s": [ 50 ], + "e": [ 0 ] + }, + { "t": 85 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.06 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p06_1_0p167_0p167" ], + "t": 75, + "s": [ 50 ], + "e": [ 100 ] + }, + { "t": 85 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 3, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 277.698, 247.258 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 7" + } + ], + "ip": 75, + "op": 179, + "st": 15, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 28, + "ty": 4, + "nm": "T1a-Y 2", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p667_1_0p167_0p167", + "t": 56, + "s": [ 39.043, 48.678, 0 ], + "e": [ 39.043, 45.678, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 64 } + ] + }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ -0.5, 9.501 ], + [ -0.048, 5.655 ], + [ 0.054, 0.06 ], + [ 0.946, 1.486 ], + [ -9.967, 8.05 ], + [ -40.546, 0 ] + ], + "o": [ + [ 0.031, -0.594 ], + [ 0.076, -8.978 ], + [ -1.161, -1.3 ], + [ -5.939, -9.327 ], + [ 24.677, -19.929 ], + [ 0, 0 ] + ], + "v": [ + [ -30.72, 63.761 ], + [ -30.741, 45.192 ], + [ -37.397, 27.014 ], + [ -40.698, 22.661 ], + [ -37.873, -7.117 ], + [ 49.506, 11.559 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.301 ], + "y": [ 0 ] + }, + "n": [ "0p833_1_0p301_0" ], + "t": 54, + "s": [ 0 ], + "e": [ 24.9 ] + }, + { "t": 70 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.667 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.301 ], + "y": [ 0 ] + }, + "n": [ "0p667_1_0p301_0" ], + "t": 54, + "s": [ 0 ], + "e": [ 100 ] + }, + { "t": 78 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.4 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 227.677, 234.375 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 9" + } + ], + "ip": 59, + "op": 179, + "st": 12, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 29, + "ty": 4, + "nm": "O-B", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p833_0p833_0p167_0p167", + "t": 31, + "s": [ -62.792, 73.057, 0 ], + "e": [ -53.792, 7.557, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.638, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.198 + }, + "n": "0p638_1_0p167_0p198", + "t": 35.257, + "s": [ -53.792, 7.557, 0 ], + "e": [ -33.667, -72.818, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ -19.1562919616699, 1.73831975460052, 0 ] + }, + { + "i": { + "x": 0.795, + "y": 1 + }, + "o": { + "x": 0.523, + "y": 0 + }, + "n": "0p795_1_0p523_0", + "t": 44, + "s": [ -33.667, -72.818, 0 ], + "e": [ -14.167, 102.182, 0 ], + "to": [ 16.2075271606445, -1.47073686122894, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.348, + "y": 1 + }, + "o": { + "x": 0.18, + "y": 0 + }, + "n": "0p348_1_0p18_0", + "t": 54, + "s": [ -14.167, 102.182, 0 ], + "e": [ -14.167, 59.182, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.27, + "y": 1 + }, + "o": { + "x": 0.693, + "y": 0 + }, + "n": "0p27_1_0p693_0", + "t": 63, + "s": [ -14.167, 59.182, 0 ], + "e": [ -14.167, 62.182, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 73 } + ] + }, + "a": { "k": [ 196.791, 266.504, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { + "k": [ + { + "i": { + "x": [ 0.667, 0.667 ], + "y": [ 1, 1 ] + }, + "o": { + "x": [ 0.333, 0.333 ], + "y": [ 0, 0 ] + }, + "n": [ "0p667_1_0p333_0", "0p667_1_0p333_0" ], + "t": 54, + "s": [ 3, 3 ], + "e": [ 44.6, 44.6 ] + }, + { "t": 61 } + ] + }, + "p": { "k": [ 0.8, -0.5 ] }, + "nm": "Ellipse Path 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 2, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 196, 267 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 0 ], + "e": [ 30 ] + }, + { + "i": { + "x": [ 0.432 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 1.124 ] + }, + "n": [ "0p432_1_0p167_1p124" ], + "t": 63, + "s": [ 30 ], + "e": [ 39.9 ] + }, + { "t": 91 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 54, + "s": [ 100 ], + "e": [ 88 ] + }, + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 63, + "s": [ 88 ], + "e": [ 88 ] + }, + { "t": 91 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + } + ], + "ip": 54, + "op": 179, + "st": 4, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 30, + "ty": 4, + "nm": "O-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p833_0p833_0p167_0p167", + "t": 31, + "s": [ -62.792, 73.057, 0 ], + "e": [ -53.792, 7.557, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.638, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.198 + }, + "n": "0p638_1_0p167_0p198", + "t": 35.257, + "s": [ -53.792, 7.557, 0 ], + "e": [ -33.667, -72.818, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ -19.1562919616699, 1.73831975460052, 0 ] + }, + { + "i": { + "x": 0.795, + "y": 1 + }, + "o": { + "x": 0.523, + "y": 0 + }, + "n": "0p795_1_0p523_0", + "t": 44, + "s": [ -33.667, -72.818, 0 ], + "e": [ -14.167, 102.182, 0 ], + "to": [ 16.2075271606445, -1.47073686122894, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.348, + "y": 1 + }, + "o": { + "x": 0.18, + "y": 0 + }, + "n": "0p348_1_0p18_0", + "t": 54, + "s": [ -14.167, 102.182, 0 ], + "e": [ -14.167, 59.182, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.27, + "y": 1 + }, + "o": { + "x": 0.693, + "y": 0 + }, + "n": "0p27_1_0p693_0", + "t": 63, + "s": [ -14.167, 59.182, 0 ], + "e": [ -14.167, 62.182, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 73 } + ] + }, + "a": { "k": [ 196.791, 266.504, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { + "k": [ + { + "i": { + "x": [ 0.667, 0.667 ], + "y": [ 1, 1 ] + }, + "o": { + "x": [ 0.333, 0.333 ], + "y": [ 0, 0 ] + }, + "n": [ "0p667_1_0p333_0", "0p667_1_0p333_0" ], + "t": 54, + "s": [ 3, 3 ], + "e": [ 44.6, 44.6 ] + }, + { "t": 61 } + ] + }, + "p": { "k": [ 0.8, -0.5 ] }, + "nm": "Ellipse Path 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.8 }, + "lc": 1, + "lj": 1, + "ml": 4, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 196, 267 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1" + } + ], + "ip": 54, + "op": 179, + "st": 4, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 31, + "ty": 4, + "nm": "T1b-B", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 1.768, -25.966 ], + [ -1.768, 25.966 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": 0, + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.21 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p21_1_0p167_0p167" ], + "t": 81, + "s": [ 11.7 ], + "e": [ 100 ] + }, + { "t": 88 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 2, + "lj": 2, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 242.756, 265.581 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 10" + } + ], + "ip": 81, + "op": 179, + "st": 26, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 32, + "ty": 4, + "nm": "T1b-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 1.768, -25.966 ], + [ -1.768, 25.966 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 70, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 75 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 70, + "s": [ 11.7 ], + "e": [ 100 ] + }, + { "t": 75 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.4 }, + "lc": 2, + "lj": 2, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 242.756, 265.581 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 10" + } + ], + "ip": 70, + "op": 161, + "st": 15, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 33, + "ty": 4, + "nm": "T2b-B", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 246.65, 213.814 ], + [ 340.956, 213.628 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 82, + "s": [ 29 ], + "e": [ 0 ] + }, + { "t": 91 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 82, + "s": [ 41.1 ], + "e": [ 66.5 ] + }, + { "t": 91 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 5" + } + ], + "ip": 82, + "op": 179, + "st": -17, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 34, + "ty": 4, + "nm": "T2a-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 1.681, -29.992 ], + [ -1.681, 29.992 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.06 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p06_1_0p167_0p167" ], + "t": 72, + "s": [ 50 ], + "e": [ 0 ] + }, + { "t": 82 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.06 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p06_1_0p167_0p167" ], + "t": 72, + "s": [ 50 ], + "e": [ 100 ] + }, + { "t": 82 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 3, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 277.698, 247.258 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 7" + } + ], + "ip": 72, + "op": 89, + "st": 12, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 35, + "ty": 4, + "nm": "T2b-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 39.043, 45.678, 0 ] }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 246.65, 213.814 ], + [ 340.956, 213.628 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 76, + "s": [ 29 ], + "e": [ 0 ] + }, + { "t": 85 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 76, + "s": [ 41.1 ], + "e": [ 66.5 ] + }, + { "t": 85 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 5" + } + ], + "ip": 76, + "op": 92, + "st": -23, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 36, + "ty": 4, + "nm": "T1a-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p667_1_0p167_0p167", + "t": 56, + "s": [ 39.043, 48.678, 0 ], + "e": [ 39.043, 45.678, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 64 } + ] + }, + "a": { "k": [ 250, 250, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ -0.5, 9.501 ], + [ -0.048, 5.655 ], + [ 0.054, 0.06 ], + [ 0.946, 1.486 ], + [ -9.967, 8.05 ], + [ -40.546, 0 ] + ], + "o": [ + [ 0.031, -0.594 ], + [ 0.076, -8.978 ], + [ -1.161, -1.3 ], + [ -5.939, -9.327 ], + [ 24.677, -19.929 ], + [ 0, 0 ] + ], + "v": [ + [ -30.72, 63.761 ], + [ -30.741, 45.192 ], + [ -37.397, 27.014 ], + [ -40.698, 22.661 ], + [ -37.873, -7.117 ], + [ 49.506, 11.559 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.301 ], + "y": [ 0 ] + }, + "n": [ "0p833_1_0p301_0" ], + "t": 54, + "s": [ 0 ], + "e": [ 24.9 ] + }, + { "t": 70 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.667 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.301 ], + "y": [ 0 ] + }, + "n": [ "0p667_1_0p301_0" ], + "t": 54, + "s": [ 0 ], + "e": [ 100 ] + }, + { "t": 74 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.4 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 227.677, 234.375 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 9" + } + ], + "ip": 59, + "op": 156, + "st": 12, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 37, + "ty": 4, + "nm": "E1-B", + "parent": 38, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 344.672, 214.842, 0 ] }, + "a": { "k": [ 344.672, 214.842, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -13.664, -0.145 ], + [ 62.163, 0.29 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.562 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 344.672, 214.842 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 2" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 0.12 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_0p12_0p167_0p167" ], + "t": 84, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 93 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 84, + "s": [ 0 ], + "e": [ 37.5 ] + }, + { "t": 93 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + } + ], + "ip": 84, + "op": 179, + "st": 84, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 38, + "ty": 4, + "nm": "E1-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.12, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p12_1_0p167_0p167", + "t": 79, + "s": [ 113.715, 9.146, 0 ], + "e": [ 137.715, 9.146, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.12, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0 + }, + "n": "0p12_1_0p167_0", + "t": 88, + "s": [ 137.715, 9.146, 0 ], + "e": [ 133.715, 9.146, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 92 } + ] + }, + "a": { "k": [ 344.672, 214.842, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -13.664, -0.145 ], + [ 62.163, 0.29 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.4 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 344.672, 214.842 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 2" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 0.12 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_0p12_0p167_0p167" ], + "t": 79, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 88 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 79, + "s": [ 0 ], + "e": [ 37.5 ] + }, + { "t": 88 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + } + ], + "ip": 79, + "op": 94, + "st": 79, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 39, + "ty": 4, + "nm": "E2-B", + "parent": 40, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 332.05, 237.932, 0 ] }, + "a": { "k": [ 332.05, 237.932, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -26.67, -0.283 ], + [ 99.171, 0.066 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 0.12 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_0p12_0p167_0p167" ], + "t": 86, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 95 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 86, + "s": [ 0 ], + "e": [ 43 ] + }, + { "t": 95 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.562 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 331.664, 238.14 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 3" + } + ], + "ip": 86, + "op": 179, + "st": 86, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 40, + "ty": 4, + "nm": "E2-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.12, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p12_1_0p167_0p167", + "t": 83, + "s": [ 109.092, 33.61, 0 ], + "e": [ 121.092, 33.61, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.12, + "y": 0.12 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p12_0p12_0p167_0p167", + "t": 92, + "s": [ 121.092, 33.61, 0 ], + "e": [ 121.092, 33.61, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 96 } + ] + }, + "a": { "k": [ 332.05, 237.932, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -26.67, -0.283 ], + [ 99.171, 0.066 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 0.12 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_0p12_0p167_0p167" ], + "t": 83, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 92 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 83, + "s": [ 0 ], + "e": [ 43 ] + }, + { "t": 92 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.4 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 331.664, 238.14 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 3" + } + ], + "ip": 83, + "op": 96, + "st": 83, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 41, + "ty": 4, + "nm": "I-B", + "parent": 42, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 303.802, 282.182, 0 ] }, + "a": { "k": [ 303.802, 282.182, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 0.859, -21.143 ], + [ -4.359, 70.392 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 0.12 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_0p12_0p167_0p167" ], + "t": 81, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 91 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 81, + "s": [ 0 ], + "e": [ 45.7 ] + }, + { "t": 91 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.194 }, + "lc": 3, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 304.135, 282.409 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 6" + } + ], + "ip": 81, + "op": 179, + "st": 18, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 42, + "ty": 4, + "nm": "I-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.12, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p12_1_0p167_0p167", + "t": 78, + "s": [ 93.594, 62.861, 0 ], + "e": [ 92.626, 82.829, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.12, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0 + }, + "n": "0p12_1_0p167_0", + "t": 88, + "s": [ 92.626, 82.829, 0 ], + "e": [ 92.844, 77.861, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 92 } + ] + }, + "a": { "k": [ 303.802, 282.182, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ 0.859, -21.143 ], + [ -4.359, 70.392 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 0.12 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_0p12_0p167_0p167" ], + "t": 78, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 88 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.12 ], + "y": [ 1 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p12_1_0p167_0p167" ], + "t": 78, + "s": [ 0 ], + "e": [ 45.7 ] + }, + { "t": 88 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 1" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 8.4 }, + "lc": 3, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 304.135, 282.409 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 6" + } + ], + "ip": 78, + "op": 93, + "st": 15, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 43, + "ty": 4, + "nm": "E3-B", + "parent": 44, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 345.189, 261.801, 0 ] }, + "a": { "k": [ 345.124, 261.801, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -13.664, -0.145 ], + [ 75.663, 0.29 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 92, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 97 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 92, + "s": [ 0 ], + "e": [ 31.6 ] + }, + { "t": 97 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 2" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.562 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 344.674, 261.877 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1" + } + ], + "ip": 92, + "op": 179, + "st": 29, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 44, + "ty": 4, + "nm": "E3-Y", + "parent": 0, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p667_1_0p167_0p167", + "t": 84, + "s": [ 119.167, 57.479, 0 ], + "e": [ 137.167, 57.479, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0 + }, + "n": "0p667_1_0p167_0", + "t": 92, + "s": [ 137.167, 57.479, 0 ], + "e": [ 134.167, 57.479, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 96 } + ] + }, + "a": { "k": [ 345.124, 261.801, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ks": { + "k": { + "i": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "o": [ + [ 0, 0 ], + [ 0, 0 ] + ], + "v": [ + [ -13.664, -0.145 ], + [ 75.663, 0.29 ] + ], + "c": false + } + }, + "nm": "Path 1" + }, + { + "ty": "tm", + "s": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 84, + "s": [ 0 ], + "e": [ 0 ] + }, + { "t": 92 } + ], + "ix": 1 + }, + "e": { + "k": [ + { + "i": { + "x": [ 0.833 ], + "y": [ 0.833 ] + }, + "o": { + "x": [ 0.167 ], + "y": [ 0.167 ] + }, + "n": [ "0p833_0p833_0p167_0p167" ], + "t": 84, + "s": [ 0 ], + "e": [ 31.6 ] + }, + { "t": 92 } + ], + "ix": 2 + }, + "o": { + "k": 0, + "ix": 3 + }, + "m": 1, + "ix": 2, + "nm": "Trim Paths 2" + }, + { + "ty": "st", + "fillEnabled": true, + "c": { "k": [ 0, 0.48, 0.53, 1 ] }, + "o": { "k": 100 }, + "w": { "k": 9.562 }, + "lc": 2, + "lj": 1, + "ml": 10, + "nm": "Stroke 1" + }, + { + "ty": "tr", + "p": { + "k": [ 344.674, 261.877 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1" + } + ], + "ip": 84, + "op": 102, + "st": 21, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 45, + "ty": 4, + "nm": "Dot-Y", + "parent": 46, + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0, + "y": 0.812 + }, + "o": { + "x": 0, + "y": 0 + }, + "n": "0_0p812_0_0", + "t": 96, + "s": [ 43.263, 59.75, 0 ], + "e": [ 62.513, 59.75, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.708, + "y": 1 + }, + "o": { + "x": 0.39, + "y": 0.707 + }, + "n": "0p708_1_0p39_0p707", + "t": 108, + "s": [ 62.513, 59.75, 0 ], + "e": [ 63.763, 59.75, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 115 } + ] + }, + "a": { "k": [ 196.791, 266.504, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { "k": [ 9.2, 9.2 ] }, + "p": { "k": [ 0.8, -0.5 ] }, + "nm": "Ellipse Path 1" + }, + { + "ty": "fl", + "fillEnabled": true, + "c": { "k": [ 1, 1, 1, 1 ] }, + "o": { "k": 100 }, + "nm": "Fill 1" + }, + { + "ty": "tr", + "p": { + "k": [ 196, 267 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1" + } + ], + "ip": 96, + "op": 182, + "st": 65, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 46, + "ty": 1, + "nm": "Bncr", + "parent": 0, + "ks": { + "o": { "k": 0 }, + "r": { "k": 0 }, + "p": { + "k": [ + { + "i": { + "x": 0.18, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p18_1_0p167_0p167", + "t": 96, + "s": [ 164.782, 57.473, 0 ], + "e": [ 164.782, 55.473, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.82, + "y": 0 + }, + "n": "0p833_0p833_0p82_0", + "t": 99, + "s": [ 164.782, 55.473, 0 ], + "e": [ 164.782, 57.473, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.18, + "y": 1 + }, + "o": { + "x": 0.167, + "y": 0.167 + }, + "n": "0p18_1_0p167_0p167", + "t": 102, + "s": [ 164.782, 57.473, 0 ], + "e": [ 164.782, 56.909, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { + "i": { + "x": 0.833, + "y": 0.833 + }, + "o": { + "x": 0.82, + "y": 0 + }, + "n": "0p833_0p833_0p82_0", + "t": 105, + "s": [ 164.782, 56.909, 0 ], + "e": [ 164.782, 57.473, 0 ], + "to": [ 0, 0, 0 ], + "ti": [ 0, 0, 0 ] + }, + { "t": 108 } + ] + }, + "a": { "k": [ 60, 60, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "sw": 120, + "sh": 120, + "sc": "#ffffff", + "ip": 96, + "op": 182, + "st": 15, + "bm": 0, + "sr": 1 + }, + { + "ddd": 0, + "ind": 47, + "ty": 4, + "nm": "BG", + "ks": { + "o": { "k": 100 }, + "r": { "k": 0 }, + "p": { "k": [ 187.5, 333.5, 0 ] }, + "a": { "k": [ 0, 0, 0 ] }, + "s": { "k": [ 100, 100, 100 ] } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "rc", + "d": 1, + "s": { "k": [ 375, 667 ] }, + "p": { "k": [ 0, 0 ] }, + "r": { "k": 0 }, + "nm": "Rectangle Path 1" + }, + { + "ty": "fl", + "fillEnabled": true, + "c": { "k": [ 0, 0.82, 0.76, 1 ] }, + "o": { "k": 100 }, + "nm": "Fill 1" + }, + { + "ty": "tr", + "p": { + "k": [ 0, 0 ], + "ix": 2 + }, + "a": { + "k": [ 0, 0 ], + "ix": 1 + }, + "s": { + "k": [ 100, 100 ], + "ix": 3 + }, + "r": { + "k": 0, + "ix": 6 + }, + "o": { + "k": 100, + "ix": 7 + }, + "sk": { + "k": 0, + "ix": 4 + }, + "sa": { + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Rectangle 1" + } + ], + "ip": 0, + "op": 179, + "st": 0, + "bm": 0, + "sr": 1 + } + ], + "v": "4.4.26", + "ddd": 0, + "ip": 0, + "op": 179, + "fr": 30, + "w": 375, + "h": 667 +} \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet1.bmp b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet1.bmp new file mode 100644 index 000000000..15d64855c Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet1.bmp differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet2.bmp b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet2.bmp new file mode 100644 index 000000000..04874cb6e Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet2.bmp differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet3.bmp b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet3.bmp new file mode 100644 index 000000000..94ca20a2d Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet3.bmp differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet4.bmp b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet4.bmp new file mode 100644 index 000000000..419f62840 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet4.bmp differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet5.bmp b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet5.bmp new file mode 100644 index 000000000..2de59e897 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet5.bmp differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet6.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet6.bin new file mode 100644 index 000000000..fda322e3e Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet6.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet7.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet7.bin new file mode 100644 index 000000000..bb4b8e255 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet7.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet8.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet8.bin new file mode 100644 index 000000000..165a93c07 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet8.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet9.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet9.bin new file mode 100644 index 000000000..a4f943700 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/DamagedHelmet9.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck1.bmp b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck1.bmp new file mode 100644 index 000000000..9fa2dd4cc Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck1.bmp differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck2.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck2.bin new file mode 100644 index 000000000..37815892d Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck2.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck3.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck3.bin new file mode 100644 index 000000000..6304bfad0 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck3.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck4.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck4.bin new file mode 100644 index 000000000..74e5472dc Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck4.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck5.bin b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck5.bin new file mode 100644 index 000000000..81dc90c73 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Assets/SceneNode/Duck5.bin differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/DrawingCsTestApp.csproj b/Samples/Islands/DrawingIsland/DrawingCsTestApp/DrawingCsTestApp.csproj new file mode 100644 index 000000000..e34e270eb --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/DrawingCsTestApp.csproj @@ -0,0 +1,57 @@ + + + + WinExe + + + net8.0-windows10.0.22621.0 + enable + enable + x64;ARM64;x86 + + + win-x86;win-x64;win-arm64 + 10.0.17763.0 + + + + False + + + + False + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/DuckScenario.cs b/Samples/Islands/DrawingIsland/DrawingCsTestApp/DuckScenario.cs new file mode 100644 index 000000000..67153b7fe --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/DuckScenario.cs @@ -0,0 +1,116 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.InteropServices; + +using Windows.Foundation; + +using Microsoft.Graphics.DirectX; +using Microsoft.UI.Composition; +using Microsoft.UI.Composition.Scenes; +using Microsoft.UI.Content; +using WinRT; +using Microsoft.Graphics.Canvas.UI.Composition; +using Microsoft.Graphics.Canvas; + + +class DuckScenario +{ + public static ContentIsland CreateIsland(Compositor compositor) + { + var visual = LoadScene_Duck(compositor); + + var island = ContentIsland.Create(visual); + return island; + } + + public static Visual LoadScene_Duck(Compositor compositor) + { + // Initialize Win2D, used for loading bitmaps. + + var canvasDevice = new CanvasDevice(); + var graphicsDevice = (CompositionGraphicsDevice)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, 360.0f); + rotateAngleAnimation.InsertKeyFrame(1.0f, 0.0f, compositor.CreateLinearEasingFunction()); + rotateAngleAnimation.Duration = TimeSpan.FromSeconds(10); + 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(4.0f); + sceneNode0.Transform.Translation = new Vector3(0.0f, -400.0f, 0.0f); + 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( + new Uri("ms-appx:///Assets/SceneNode/Duck2.bin")); + + var normalData = SceneNodeCommon.LoadMemoryBufferFromUriAsync( + new Uri("ms-appx:///Assets/SceneNode/Duck3.bin")); + + var texCoordData = SceneNodeCommon.LoadMemoryBufferFromUriAsync( + new Uri("ms-appx:///Assets/SceneNode/Duck4.bin")); + + var indexData = SceneNodeCommon.LoadMemoryBufferFromUriAsync( + new Uri("ms-appx:///Assets/SceneNode/Duck5.bin")); + + var canvasBitmap0 = CanvasBitmap.LoadAsync( + canvasDevice, new Uri("ms-appx:///Assets/SceneNode/Duck1.bmp")).AsTask(); + + Task.WaitAll( + vertexData, normalData, texCoordData, indexData, canvasBitmap0); + + + // Generate mipmaps from the bitmaps, which are needed for 3D rendering. + + var materialInput0 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap0.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"); ; + + return sceneVisual; + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/HelmetScenario.cs b/Samples/Islands/DrawingIsland/DrawingCsTestApp/HelmetScenario.cs new file mode 100644 index 000000000..cfaf01278 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/HelmetScenario.cs @@ -0,0 +1,155 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.InteropServices; + +using Windows.Foundation; +using Windows.Graphics; +using Windows.Storage; +using Windows.Storage.Streams; + +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 ContentIsland CreateIsland(Compositor compositor) + { + var visual = LoadScene_DamagedHelmet(compositor); + + var island = ContentIsland.Create(visual); + return island; + } + + private static 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(350); + 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( + new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet6.bin")); + + var normalData = SceneNodeCommon.LoadMemoryBufferFromUriAsync( + new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet7.bin")); + + var texCoordData = SceneNodeCommon.LoadMemoryBufferFromUriAsync( + new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet8.bin")); + + var indexData = SceneNodeCommon.LoadMemoryBufferFromUriAsync( + new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet9.bin")); + + var canvasBitmap0 = CanvasBitmap.LoadAsync( + canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet1.bmp")).AsTask(); + + var canvasBitmap1 = CanvasBitmap.LoadAsync( + canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet2.bmp")).AsTask(); + + var canvasBitmap2 = CanvasBitmap.LoadAsync( + canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet3.bmp")).AsTask(); + + var canvasBitmap3 = CanvasBitmap.LoadAsync( + canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet4.bmp")).AsTask(); + + var canvasBitmap4 = CanvasBitmap.LoadAsync( + canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet5.bmp")).AsTask(); + + Task.WaitAll( + vertexData, normalData, texCoordData, indexData, + canvasBitmap0, canvasBitmap1, canvasBitmap2, canvasBitmap3, 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; + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/LottieIslandScenario.cs b/Samples/Islands/DrawingIsland/DrawingCsTestApp/LottieIslandScenario.cs new file mode 100644 index 000000000..e5a8c5acd --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/LottieIslandScenario.cs @@ -0,0 +1,36 @@ +using Microsoft.UI.Composition; +using CommunityToolkit.WinAppSDK.LottieIsland; +using CommunityToolkit.WinAppSDK.LottieWinRT; + +class LottieIslandScenario +{ + public static LottieContentIsland CreateLottieIsland(Compositor compositor) + { + var lottieIsland = LottieContentIsland.Create(compositor); + var lottieVisualSource = LottieVisualSourceWinRT.CreateFromString( + "ms-appx:///Assets/LottieLogo1.json"); + + if (lottieVisualSource != null) + { + lottieVisualSource.AnimatedVisualInvalidated += (sender, args) => + { + object? diagnostics = null; + IAnimatedVisualFrameworkless? animatedVisual = + lottieVisualSource.TryCreateAnimatedVisual(compositor, out diagnostics); + + if (animatedVisual != null) + { + // This callback comes back on a different thread, so set the AnimatedVisual on + // the UI thread + compositor.DispatcherQueue.TryEnqueue(async () => + { + lottieIsland.AnimatedVisual = animatedVisual; + await lottieIsland.PlayAsync(0, 1, true); + }); + } + }; + } + + return lottieIsland; + } +} \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Program.cs b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Program.cs new file mode 100644 index 000000000..1624ef9b9 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Program.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#region Using directives +using Microsoft.UI.Composition; +using Microsoft.UI.Content; +using Microsoft.UI.Dispatching; +using Microsoft.UI.Input; +using Microsoft.UI.Windowing; + +using DrawingIslandComponents; +#endregion + +var controller = DispatcherQueueController.CreateOnCurrentThread(); +var queue = controller.DispatcherQueue; + +// Associate the AppWindow's lifetime with the DispatcherQueue to automatically close on exit. +var window = AppWindow.Create(); +window.AssociateWithDispatcherQueue(queue); +window.Closing +=(sender, args) => + { + // Ensure the DispatcherQueue exits the event loop on close. + queue.EnqueueEventLoopExit(); + }; + +window.Title = "Drawing C# .NET TestApp"; +window.Show(); + +#region ... +// Create a ContentSiteBridge and connect Island content into it. +var compositor = new Compositor(); +var siteBridge = DesktopChildSiteBridge.Create(compositor, window.Id); +siteBridge.ResizePolicy = ContentSizePolicy.ResizeContentToParentWindow; +siteBridge.Show(); + +var drawing = new DrawingIsland(compositor); +siteBridge.Connect(drawing.Island); + +#region ... +//var lottie = LottieIslandScenario.CreateLottieIsland(compositor); +//siteBridge.Connect(lottie.Island); + +#region ... +//var island = HelmetScenario.CreateIsland(compositor); +//siteBridge.Connect(island); + +#endregion +#endregion + +// Move initial focus to the ContentIsland. +var focusNavigationHost = InputFocusNavigationHost.GetForSiteBridge(siteBridge); +focusNavigationHost.NavigateFocus(FocusNavigationRequest.Create( + FocusNavigationReason.Programmatic)); +#endregion + +queue.RunEventLoop(); + +controller.ShutdownQueue(); diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/SceneNodeCommon.cs b/Samples/Islands/DrawingIsland/DrawingCsTestApp/SceneNodeCommon.cs new file mode 100644 index 000000000..d18bc4d7e --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/SceneNodeCommon.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using Windows.Foundation; +using Windows.Storage.Streams; +using Windows.Storage; +using WinRT; +using Microsoft.Graphics.Canvas.UI.Composition; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.DirectX; +using Microsoft.UI.Composition; +using Microsoft.UI.Composition.Scenes; +using Windows.Graphics; + +class SceneNodeCommon +{ + public static CompositionMipmapSurface LoadMipmapFromBitmap( + CompositionGraphicsDevice graphicsDevice, CanvasBitmap canvasBitmap) + { + var size = new SizeInt32(2048, 2048); + var mipmapSurface = graphicsDevice.CreateMipmapSurface( + size, + DirectXPixelFormat.B8G8R8A8UIntNormalized, + DirectXAlphaMode.Premultiplied); + + var drawDestRect = new Rect(0, 0, size.Width, size.Height); + var drawSourceRect = new Rect(0, 0, size.Width, size.Height); + for (uint level = 0; level < mipmapSurface.LevelCount; ++level) + { + // Draw the image to the surface + var drawingSurface = mipmapSurface.GetDrawingSurfaceForLevel(level); + + using (var session = CanvasComposition.CreateDrawingSession(drawingSurface)) + { + session.Clear(Windows.UI.Color.FromArgb(0, 0, 0, 0)); + session.DrawImage(canvasBitmap, drawDestRect, drawSourceRect); + } + + drawDestRect = new Rect(0, 0, drawDestRect.Width / 2, drawDestRect.Height / 2); + } + + return mipmapSurface; + } + + public static SceneSurfaceMaterialInput CreateMaterial( + Compositor compositor, + CompositionMipmapSurface mipmap, + SceneMeshRendererComponent rendererComponent, + string mapping) + { + var materialInput = SceneSurfaceMaterialInput.Create(compositor); + materialInput.Surface = mipmap; + materialInput.BitmapInterpolationMode = + CompositionBitmapInterpolationMode.MagLinearMinLinearMipLinear; + + materialInput.WrappingUMode = SceneWrappingMode.Repeat; + materialInput.WrappingVMode = SceneWrappingMode.Repeat; + + rendererComponent.UVMappings[mapping] = SceneAttributeSemantic.TexCoord0; + + return materialInput; + } + + public static async Task LoadMemoryBufferFromUriAsync(Uri uri) + { + var file = await StorageFile.GetFileFromApplicationUriAsync(uri); + var buffer = await FileIO.ReadBufferAsync(file); + + return CopyToMemoryBuffer(buffer); + } + + public static MemoryBuffer CopyToMemoryBuffer(IBuffer buffer) + { + var dataReader = DataReader.FromBuffer(buffer); + + var memBuffer = new MemoryBuffer(buffer.Length); + var memBufferRef = memBuffer.CreateReference(); + var memBufferByteAccess = memBufferRef.As(); + + unsafe + { + byte* bytes = null; + uint capacity; + memBufferByteAccess.GetBuffer(&bytes, &capacity); + + for (int i = 0; i < capacity; ++i) + { + bytes[i] = dataReader.ReadByte(); + } + } + + return memBuffer; + } + + + public static MemoryBuffer CopyToMemoryBuffer(byte[] a) + { + MemoryBuffer mb = new MemoryBuffer((uint)a.Length); + var mbr = mb.CreateReference(); + var mba = mbr.As(); + unsafe + { + byte* bytes = null; + uint capacity; + mba.GetBuffer(&bytes, &capacity); + for (int i = 0; i < capacity; ++i) + { + bytes[i] = a[i]; + } + } + + return mb; + } + + + + [ComImport, + Guid("5b0d3235-4dba-4d44-865e-8f1d0e4fd04d"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMemoryBufferByteAccess + { + unsafe void GetBuffer(byte** bytes, uint* capacity); + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/DrawingCsTestPackage.wapproj b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/DrawingCsTestPackage.wapproj new file mode 100644 index 000000000..5d130fa8d --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/DrawingCsTestPackage.wapproj @@ -0,0 +1,66 @@ + + + + 15.0 + + + + Debug + x86 + + + Release + x86 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\ + + + + 3ed80af8-0d53-4568-8a9a-bcb852b85dc7 + 10.0.22621.0 + 10.0.17763.0 + en-US + false + $(NoWarn);NU1702 + ..\DrawingCsTestApp\DrawingCsTestApp.csproj + + + + Designer + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/LockScreenLogo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/LockScreenLogo.scale-200.png new file mode 100644 index 000000000..735f57adb Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/LockScreenLogo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/SplashScreen.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/SplashScreen.scale-200.png new file mode 100644 index 000000000..023e7f1fe Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/SplashScreen.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square150x150Logo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square150x150Logo.scale-200.png new file mode 100644 index 000000000..af49fec1a Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square150x150Logo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square44x44Logo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square44x44Logo.scale-200.png new file mode 100644 index 000000000..ce342a2ec Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square44x44Logo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 000000000..f6c02ce97 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/StoreLogo.png b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/StoreLogo.png new file mode 100644 index 000000000..7385b56c0 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/StoreLogo.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Wide310x150Logo.scale-200.png b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Wide310x150Logo.scale-200.png new file mode 100644 index 000000000..288995b39 Binary files /dev/null and b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Images/Wide310x150Logo.scale-200.png differ diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Package.appxmanifest b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Package.appxmanifest new file mode 100644 index 000000000..237dc5eaa --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingCsTestPackage/Package.appxmanifest @@ -0,0 +1,48 @@ + + + + + + + + DrawingCsDotNetTestApp + Microsoft Corporation (jstall) + Images\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/Islands/DrawingIsland/DrawingIsland.sln b/Samples/Islands/DrawingIsland/DrawingIsland.sln new file mode 100644 index 000000000..74fb743d9 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIsland.sln @@ -0,0 +1,119 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34728.123 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DrawingCppTestApp", "DrawingCppTestApp\DrawingCppTestApp.vcxproj", "{74605FC4-2E57-459F-947B-AEF9F6921AE8}" +EndProject +Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "DrawingCppTestPackage", "DrawingCppTestPackage\DrawingCppTestPackage.wapproj", "{3099B355-5306-4814-BC1C-08AB3F29B32E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DrawingIslandComponents", "DrawingIslandComponents\DrawingIslandComponents.vcxproj", "{709C54E1-0F2F-4A59-80B2-4CFD08B720E5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DrawingCsTestApp", "DrawingCsTestApp\DrawingCsTestApp.csproj", "{97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}" +EndProject +Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "DrawingCsTestPackage", "DrawingCsTestPackage\DrawingCsTestPackage.wapproj", "{3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawingIslandCsProjection", "DrawingIslandCsProjection\DrawingIslandCsProjection.csproj", "{48847923-880A-4A61-99CF-64B8EABD412B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Debug|ARM64.Build.0 = Debug|ARM64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Debug|x64.ActiveCfg = Debug|x64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Debug|x64.Build.0 = Debug|x64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Debug|x86.ActiveCfg = Debug|Win32 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Debug|x86.Build.0 = Debug|Win32 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Release|ARM64.ActiveCfg = Release|ARM64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Release|ARM64.Build.0 = Release|ARM64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Release|x64.ActiveCfg = Release|x64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Release|x64.Build.0 = Release|x64 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Release|x86.ActiveCfg = Release|Win32 + {74605FC4-2E57-459F-947B-AEF9F6921AE8}.Release|x86.Build.0 = Release|Win32 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|ARM64.Build.0 = Debug|ARM64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|x64.ActiveCfg = Debug|x64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|x64.Build.0 = Debug|x64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|x64.Deploy.0 = Debug|x64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|x86.ActiveCfg = Debug|x86 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|x86.Build.0 = Debug|x86 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Debug|x86.Deploy.0 = Debug|x86 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|ARM64.ActiveCfg = Release|ARM64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|ARM64.Build.0 = Release|ARM64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|ARM64.Deploy.0 = Release|ARM64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|x64.ActiveCfg = Release|x64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|x64.Build.0 = Release|x64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|x64.Deploy.0 = Release|x64 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|x86.ActiveCfg = Release|x86 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|x86.Build.0 = Release|x86 + {3099B355-5306-4814-BC1C-08AB3F29B32E}.Release|x86.Deploy.0 = Release|x86 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|ARM64.Build.0 = Debug|ARM64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x64.ActiveCfg = Debug|x64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x64.Build.0 = Debug|x64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x86.ActiveCfg = Debug|Win32 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x86.Build.0 = Debug|Win32 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|ARM64.ActiveCfg = Release|ARM64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|ARM64.Build.0 = Release|ARM64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x64.ActiveCfg = Release|x64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x64.Build.0 = Release|x64 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x86.ActiveCfg = Release|Win32 + {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x86.Build.0 = Release|Win32 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Debug|ARM64.Build.0 = Debug|ARM64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Debug|x64.ActiveCfg = Debug|x64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Debug|x64.Build.0 = Debug|x64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Debug|x86.ActiveCfg = Debug|x86 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Debug|x86.Build.0 = Debug|x86 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Release|ARM64.ActiveCfg = Release|ARM64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Release|ARM64.Build.0 = Release|ARM64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Release|x64.ActiveCfg = Release|x64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Release|x64.Build.0 = Release|x64 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Release|x86.ActiveCfg = Release|x86 + {97AA2E60-6FBB-4D54-A87D-BA42BC0CC3D3}.Release|x86.Build.0 = Release|x86 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|ARM64.Build.0 = Debug|ARM64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|x64.ActiveCfg = Debug|x64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|x64.Build.0 = Debug|x64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|x64.Deploy.0 = Debug|x64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|x86.ActiveCfg = Debug|x86 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|x86.Build.0 = Debug|x86 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Debug|x86.Deploy.0 = Debug|x86 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|ARM64.ActiveCfg = Release|ARM64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|ARM64.Build.0 = Release|ARM64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|ARM64.Deploy.0 = Release|ARM64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|x64.ActiveCfg = Release|x64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|x64.Build.0 = Release|x64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|x64.Deploy.0 = Release|x64 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|x86.ActiveCfg = Release|x86 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|x86.Build.0 = Release|x86 + {3ED80AF8-0D53-4568-8A9A-BCB852B85DC7}.Release|x86.Deploy.0 = Release|x86 + {48847923-880A-4A61-99CF-64B8EABD412B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Debug|ARM64.Build.0 = Debug|ARM64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Debug|x64.ActiveCfg = Debug|x64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Debug|x64.Build.0 = Debug|x64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Debug|x86.ActiveCfg = Debug|x86 + {48847923-880A-4A61-99CF-64B8EABD412B}.Debug|x86.Build.0 = Debug|x86 + {48847923-880A-4A61-99CF-64B8EABD412B}.Release|ARM64.ActiveCfg = Release|ARM64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Release|ARM64.Build.0 = Release|ARM64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Release|x64.ActiveCfg = Release|x64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Release|x64.Build.0 = Release|x64 + {48847923-880A-4A61-99CF-64B8EABD412B}.Release|x86.ActiveCfg = Release|x86 + {48847923-880A-4A61-99CF-64B8EABD412B}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {85542A88-746B-4646-9027-3AA360D075C2} + EndGlobalSection +EndGlobal diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationCallbackHandler.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationCallbackHandler.h new file mode 100644 index 000000000..f61638cd1 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationCallbackHandler.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +namespace winrt::DrawingIslandComponents +{ + struct __declspec(novtable) IAutomationCallbackHandler + { + virtual ~IAutomationCallbackHandler() noexcept = default; + + virtual winrt::Windows::Graphics::RectInt32 GetScreenBoundsForAutomationFragment( + _In_::IUnknown const* const sender) const = 0; + + virtual winrt::com_ptr GetFragmentFromPoint( + _In_ double x, + _In_ double y) const = 0; + + virtual winrt::com_ptr GetFragmentInFocus() const = 0; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragment.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragment.cpp new file mode 100644 index 000000000..83691aa66 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragment.cpp @@ -0,0 +1,464 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include "AutomationFragment.h" + +using unique_safearray = + wil::unique_any; + +namespace winrt::DrawingIslandComponents +{ + void AutomationFragment::AddChildToEnd( + _In_ winrt::com_ptr const& child) + { + std::unique_lock lock{ m_mutex }; + + if (nullptr == child) + { + // Nothing to do. + return; + } + + // The child should not already have a parent. + winrt::check_bool(nullptr == child->GetParent()); + + // Set us up as the parent for the new child. + child->SetParent(get_weak()); + + // Set up the sibling relationships. + if (!m_children.empty()) + { + auto& previousSiblingForNewChild = m_children.back(); + previousSiblingForNewChild->SetNextSibling(child); + child->SetPreviousSibling(previousSiblingForNewChild); + } + + // Finally add the child. + m_children.push_back(child); + } + + void AutomationFragment::RemoveChild( + _In_ winrt::com_ptr const& child) + { + std::unique_lock lock{ m_mutex }; + + if (nullptr == child) + { + // Nothing to do. + return; + } + + auto iterator = std::find_if( + m_children.begin(), m_children.end(), [&child](auto const& childEntry) + { + // See if we find a matching child entry in our children. + return (childEntry.get() == child.get()); + }); + + // We cannot remove a child that isn't ours. + winrt::check_bool(m_children.end() != iterator); + + // Remove us from the parent relationship with the child. + child->SetParent(nullptr); + + // Reset the sibling relationships. + auto previousSibling = child->GetPreviousSibling(); + auto nextSibling = child->GetNextSibling(); + if (nullptr != previousSibling) + { + previousSibling->SetNextSibling(nextSibling); + } + if (nullptr != nextSibling) + { + nextSibling->SetPreviousSibling(previousSibling); + } + child->SetPreviousSibling(nullptr); + child->SetNextSibling(nullptr); + + // Finally, remove the child. + m_children.erase(iterator); + } + + void AutomationFragment::RemoveAllChildren() + { + std::unique_lock lock{ m_mutex }; + + for (auto& child : m_children) + { + // Disconnect the relationships from all our children. + child->SetParent(nullptr); + child->SetPreviousSibling(nullptr); + child->SetNextSibling(nullptr); + } + + // Remove all the children. + m_children.clear(); + } + + void AutomationFragment::SetCallbackHandler( + _In_opt_ IAutomationCallbackHandler const* const owner) + { + std::unique_lock lock{ m_mutex }; + m_ownerNoRef = owner; + } + + void AutomationFragment::SetProviderOptions( + _In_ ProviderOptions const& providerOptions) + { + std::unique_lock lock{ m_mutex }; + m_providerOptions = providerOptions; + } + + void AutomationFragment::SetName( + _In_ std::wstring_view const& name) + { + std::unique_lock lock{ m_mutex }; + m_name = name; + } + + void AutomationFragment::SetIsContent( + _In_ bool const& isContent) + { + std::unique_lock lock{ m_mutex }; + m_isContent = isContent; + } + + void AutomationFragment::SetIsControl( + _In_ bool const& isControl) + { + std::unique_lock lock{ m_mutex }; + m_isControl = isControl; + } + + void AutomationFragment::SetUiaControlTypeId( + _In_ long const& uiaControlTypeId) + { + std::unique_lock lock{ m_mutex }; + m_uiaControlTypeId = uiaControlTypeId; + } + + void AutomationFragment::SetHostProvider( + _In_ winrt::com_ptr const& hostProvider) + { + std::unique_lock lock{ m_mutex }; + m_hostProvider = hostProvider; + } + + HRESULT __stdcall AutomationFragment::get_ProviderOptions( + _Out_ ProviderOptions* providerOptions) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != providerOptions) + { + *providerOptions = m_providerOptions; + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::GetPatternProvider( + _In_ PATTERNID patternId, + _COM_Outptr_opt_result_maybenull_ IUnknown** patternProvider) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != patternProvider) + { + *patternProvider = nullptr; + switch (patternId) + { + case UIA_InvokePatternId: + { + if (auto invokeProvider = get_strong().try_as()) + { + invokeProvider.as().copy_to(patternProvider); + } + break; + } + } + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::GetPropertyValue( + _In_ PROPERTYID propertyId, + _Out_ VARIANT* propertyValue) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != propertyValue) + { + ::VariantInit(propertyValue); + switch (propertyId) + { + case UIA_NamePropertyId: + { + propertyValue->bstrVal = wil::make_bstr(m_name.c_str()).release(); + propertyValue->vt = VT_BSTR; + break; + } + + case UIA_IsContentElementPropertyId: + { + propertyValue->boolVal = m_isContent ? VARIANT_TRUE : VARIANT_FALSE; + propertyValue->vt = VT_BOOL; + break; + } + + case UIA_IsControlElementPropertyId: + { + propertyValue->boolVal = m_isControl ? VARIANT_TRUE : VARIANT_FALSE; + propertyValue->vt = VT_BOOL; + break; + } + + case UIA_ControlTypePropertyId: + { + if (m_isControl) + { + propertyValue->vt = VT_I4; + propertyValue->lVal = m_uiaControlTypeId; + } + break; + } + } + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::get_HostRawElementProvider( + _COM_Outptr_opt_result_maybenull_ IRawElementProviderSimple** hostRawElementProviderSimple) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != hostRawElementProviderSimple) + { + m_hostProvider.copy_to(hostRawElementProviderSimple); + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::Navigate( + _In_ NavigateDirection direction, + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != fragment) + { + *fragment = nullptr; + switch (direction) + { + case NavigateDirection_Parent: + { + if (auto strongParent = m_parent.get()) + { + strongParent.as().copy_to(fragment); + } + break; + } + case NavigateDirection_NextSibling: + { + if (auto strongSibling = m_nextSibling.get()) + { + strongSibling.as().copy_to(fragment); + } + break; + } + case NavigateDirection_PreviousSibling: + { + if (auto strongSibling = m_previousSibling.get()) + { + strongSibling.as().copy_to(fragment); + } + break; + } + case NavigateDirection_FirstChild: + { + if (!m_children.empty()) + { + m_children.front().as().copy_to(fragment); + } + break; + } + case NavigateDirection_LastChild: + { + if (!m_children.empty()) + { + m_children.back().as().copy_to(fragment); + } + break; + } + } + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::GetRuntimeId( + _Outptr_opt_result_maybenull_ SAFEARRAY** runtimeId) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != runtimeId) + { + *runtimeId = nullptr; + + unsigned long arraySizeAsUnsignedLong = + static_cast(m_runtimeId.size()); + + unique_safearray runtimeIdArray + { ::SafeArrayCreateVector(VT_I4, 0, arraySizeAsUnsignedLong) }; + SAFEARRAY* rawPointerToSafeArray = runtimeIdArray.get(); + winrt::check_pointer(rawPointerToSafeArray); + + for (long i = 0; i < static_cast(arraySizeAsUnsignedLong); ++i) + { + winrt::check_hresult( + ::SafeArrayPutElement(rawPointerToSafeArray, &i, &(m_runtimeId[i]))); + } + + *runtimeId = runtimeIdArray.release(); + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::get_BoundingRectangle( + _Out_ UiaRect* boundingRectangle) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != boundingRectangle) + { + *boundingRectangle = { 0, 0, 0, 0 }; + + // This provider might still be alive in a UIA callback when the DrawingIsland + // is being torn down. Make sure we still have a valid owner before proceeding + // to query the DrawingIsland for this information. + if (nullptr != m_ownerNoRef) + { + auto screenRectangle = + m_ownerNoRef->GetScreenBoundsForAutomationFragment( + get_strong().as<::IUnknown>().get()); + + boundingRectangle->left = screenRectangle.X; + boundingRectangle->top = screenRectangle.Y; + boundingRectangle->width = screenRectangle.Width; + boundingRectangle->height = screenRectangle.Height; + } + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::GetEmbeddedFragmentRoots( + _Outptr_opt_result_maybenull_ SAFEARRAY** embeddedFragmentRoots) + { + if (nullptr != embeddedFragmentRoots) + { + *embeddedFragmentRoots = nullptr; + } + return S_OK; + } + + HRESULT __stdcall AutomationFragment::SetFocus() + { + return S_OK; + } + + HRESULT __stdcall AutomationFragment::get_FragmentRoot( + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragmentRoot** fragmentRoot) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != fragmentRoot) + { + *fragmentRoot = nullptr; + + // Walk up our fragment tree until we find our fragment root. + auto fragmentRootCandidate = get_strong(); + bool currentCandidateIsThisObject = true; + while (nullptr != fragmentRootCandidate && + nullptr == fragmentRootCandidate.try_as()) + { + // Haven't found the fragment root yet, keep walking up our tree. + fragmentRootCandidate = currentCandidateIsThisObject ? + m_parent.get() : fragmentRootCandidate->GetParent(); + + // Once we start walking up the tree, we must ensure we're thread-safe + // and call through GetParent on the other objects. + currentCandidateIsThisObject = false; + } + + if (nullptr != fragmentRootCandidate) + { + // Found the fragment root, return it. + fragmentRootCandidate.as().copy_to( + fragmentRoot); + } + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + void AutomationFragment::SetParent( + _In_ winrt::weak_ref const& parent) + { + std::unique_lock lock{ m_mutex }; + m_parent = parent; + } + + winrt::com_ptr AutomationFragment::GetParent() const + { + std::unique_lock lock{ m_mutex }; + return m_parent.get(); + } + + void AutomationFragment::SetPreviousSibling( + _In_ winrt::weak_ref const& previousSibling) + { + std::unique_lock lock{ m_mutex }; + m_previousSibling = previousSibling; + } + + winrt::com_ptr AutomationFragment::GetPreviousSibling() const + { + std::unique_lock lock{ m_mutex }; + return m_previousSibling.get(); + } + + void AutomationFragment::SetNextSibling( + _In_ winrt::weak_ref const& nextSibling) + { + std::unique_lock lock{ m_mutex }; + m_nextSibling = nextSibling; + } + + winrt::com_ptr AutomationFragment::GetNextSibling() const + { + std::unique_lock lock{ m_mutex }; + return m_nextSibling.get(); + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragment.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragment.h new file mode 100644 index 000000000..c05629c0c --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragment.h @@ -0,0 +1,129 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once +#include +#include "AutomationCallbackHandler.h" + +namespace winrt::DrawingIslandComponents +{ + struct AutomationFragment : winrt::implements + { + void AddChildToEnd( + _In_ winrt::com_ptr const& child); + + void RemoveChild( + _In_ winrt::com_ptr const& child); + + void RemoveAllChildren(); + + void SetCallbackHandler( + _In_opt_ IAutomationCallbackHandler const* const owner); + + void SetProviderOptions( + _In_ ProviderOptions const& providerOptions); + + void SetName( + _In_ std::wstring_view const& name); + + void SetIsContent( + _In_ bool const& isContent); + + void SetIsControl( + _In_ bool const& isControl); + + void SetUiaControlTypeId( + _In_ long const& uiaControlTypeId); + + void SetHostProvider( + _In_ winrt::com_ptr const& hostProvider); + + // IRawElementProviderSimple overrides. + HRESULT __stdcall get_ProviderOptions( + _Out_ ProviderOptions* providerOptions + ) final override; + + HRESULT __stdcall GetPatternProvider( + _In_ PATTERNID patternId, + _COM_Outptr_opt_result_maybenull_ IUnknown** patternProvider + ) final override; + + HRESULT __stdcall GetPropertyValue( + _In_ PROPERTYID propertyId, + _Out_ VARIANT* propertyValue + ) final override; + + HRESULT __stdcall get_HostRawElementProvider( + _COM_Outptr_opt_result_maybenull_ IRawElementProviderSimple** hostRawElementProviderSimple + ) final override; + + // IRawElementProviderFragment overrides. + HRESULT __stdcall Navigate( + _In_ NavigateDirection direction, + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment + ) final override; + + HRESULT __stdcall GetRuntimeId( + _Outptr_opt_result_maybenull_ SAFEARRAY** runtimeId + ) final override; + + HRESULT __stdcall get_BoundingRectangle( + _Out_ UiaRect* boundingRectangle + ) final override; + + HRESULT __stdcall GetEmbeddedFragmentRoots( + _Outptr_opt_result_maybenull_ SAFEARRAY** embeddedFragmentRoots + ) final override; + + HRESULT __stdcall SetFocus() final override; + + HRESULT __stdcall get_FragmentRoot( + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragmentRoot** fragmentRoot + ) final override; + + protected: + mutable std::mutex m_mutex{}; + + // We do not hold a strong reference to the object that owns us. + // However we do need to be able to call back into it to get information. + // The owner is responsible for unsetting itself when it gets destroyed. + IAutomationCallbackHandler const* m_ownerNoRef{ nullptr }; + + private: + void SetParent( + _In_ winrt::weak_ref const& parent); + + winrt::com_ptr GetParent() const; + + void SetPreviousSibling( + _In_ winrt::weak_ref const& previousSibling); + + winrt::com_ptr GetPreviousSibling() const; + + void SetNextSibling( + _In_ winrt::weak_ref const& nextSibling); + + winrt::com_ptr GetNextSibling() const; + + // Automatically generate unique runtime IDs per fragment. + inline static unsigned __int32 s_nextAvailableInternalRuntimeId{ 0 }; + std::array m_runtimeId + { UiaAppendRuntimeId, ++s_nextAvailableInternalRuntimeId }; + + ProviderOptions m_providerOptions + { ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading }; + std::wstring m_name{ L"" }; + bool m_isContent{ true }; + bool m_isControl{ true }; + long m_uiaControlTypeId{ UIA_CustomControlTypeId }; + winrt::com_ptr m_hostProvider{ nullptr }; + + winrt::weak_ref m_parent{ nullptr }; + winrt::weak_ref m_previousSibling{ nullptr }; + winrt::weak_ref m_nextSibling{ nullptr }; + std::vector> m_children{}; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragmentRoot.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragmentRoot.cpp new file mode 100644 index 000000000..f8833f010 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragmentRoot.cpp @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include "AutomationFragmentRoot.h" + +namespace winrt::DrawingIslandComponents +{ + HRESULT __stdcall AutomationFragmentRoot::ElementProviderFromPoint( + _In_ double x, + _In_ double y, + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != fragment) + { + *fragment = nullptr; + + // This provider might still be alive in a UIA callback when the DrawingIsland + // is being torn down. Make sure we still have a valid owner before proceeding + // to query the DrawingIsland for this information. + if (nullptr != m_ownerNoRef) + { + m_ownerNoRef->GetFragmentFromPoint(x, y).copy_to(fragment); + } + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } + + HRESULT __stdcall AutomationFragmentRoot::GetFocus( + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragmentInFocus) + { + try + { + std::unique_lock lock{ m_mutex }; + if (nullptr != fragmentInFocus) + { + *fragmentInFocus = nullptr; + + // This provider might still be alive in a UIA callback when the DrawingIsland + // is being torn down. Make sure we still have a valid owner before proceeding + // to query the DrawingIsland for this information. + if (nullptr != m_ownerNoRef) + { + m_ownerNoRef->GetFragmentInFocus().copy_to(fragmentInFocus); + } + } + } + catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; } + return S_OK; + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragmentRoot.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragmentRoot.h new file mode 100644 index 000000000..60e629c73 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationFragmentRoot.h @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once +#include "AutomationFragment.h" + +namespace winrt::DrawingIslandComponents +{ + struct AutomationFragmentRoot : winrt::implements + { + // IRawElementProviderFragmentRoot overrides. + HRESULT __stdcall ElementProviderFromPoint( + _In_ double x, + _In_ double y, + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment + ) final override; + + HRESULT __stdcall GetFocus( + _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragmentInFocus + ) final override; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationPeer.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationPeer.h new file mode 100644 index 000000000..e47b6fce8 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/AutomationPeer.h @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +namespace winrt::DrawingIslandComponents +{ + // For the DrawingIsland, each Visual corresponds to an Automation Fragment. + // This structure encapsulates that relationship and enables us to quickly retrieve one from + // the other. + struct AutomationPeer + { + explicit AutomationPeer( + winrt::Visual const& visual, + winrt::com_ptr const& automationProvider) : + _visual{ visual }, + _automationProvider{ automationProvider } + { + + } + + winrt::Visual const& GetVisual() const + { + return _visual; + } + + winrt::com_ptr const& GetAutomationProvider() const + { + return _automationProvider; + } + + bool Match(winrt::Visual const& visual) const noexcept + { + return visual == _visual; + } + + bool Match(::IUnknown const* const automationProviderAsIUnknown) const noexcept + { + return automationProviderAsIUnknown == + _automationProvider.try_as<::IUnknown>().get(); + } + + private: + winrt::Visual _visual{ nullptr }; + winrt::com_ptr _automationProvider{ nullptr }; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/Components.idl b/Samples/Islands/DrawingIsland/DrawingIslandComponents/Components.idl new file mode 100644 index 000000000..0a17ee88a --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/Components.idl @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace DrawingIslandComponents +{ + [default_interface] + runtimeclass DrawingIsland : Windows.Foundation.IClosable + { + // Construction + DrawingIsland( + Microsoft.UI.Composition.Compositor compositor); + + // Properties + Boolean EnableBackgroundTransparency; + + Microsoft.UI.Content.ContentIsland Island { get; }; + + // Methods + void LeftClickAndRelease( + Windows.Foundation.Numerics.Vector2 currentPoint); + + void RightClickAndRelease( + Windows.Foundation.Numerics.Vector2 currentPoint); + + void SetIslandOpacity(Single islandOpacity); + + void SetColorIndex(UInt32 colorIndex); + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DeviceLostHelper.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DeviceLostHelper.cpp new file mode 100644 index 000000000..3a19e2af4 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DeviceLostHelper.cpp @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include "DeviceLostHelper.h" + +namespace winrt::DrawingIslandComponents::implementation +{ + void DeviceLostHelper::WatchDevice(winrt::com_ptr<::IDXGIDevice> const& dxgiDevice) + { + // If we're currently listening to a device, then stop. + StopWatchingCurrentDevice(); + + // Set the current device to the new device. + m_device = nullptr; + winrt::check_hresult(::CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), reinterpret_cast<::IInspectable**>(winrt::put_abi(m_device)))); + + // Get the DXGI Device. + m_dxgiDevice = dxgiDevice; + + // QI For the ID3D11Device4 interface. + winrt::com_ptr<::ID3D11Device4> d3dDevice{ m_dxgiDevice.as<::ID3D11Device4>() }; + + // Create a wait struct. + m_onDeviceLostHandler = nullptr; + m_onDeviceLostHandler = ::CreateThreadpoolWait(DeviceLostHelper::OnDeviceLost, (PVOID)this, nullptr); + + // Create a handle and a cookie. + m_eventHandle.attach(::CreateEvent(nullptr, false, false, nullptr)); + winrt::check_bool(bool{ m_eventHandle }); + m_cookie = 0; + + // Register for device lost. + ::SetThreadpoolWait(m_onDeviceLostHandler, m_eventHandle.get(), nullptr); + winrt::check_hresult(d3dDevice->RegisterDeviceRemovedEvent(m_eventHandle.get(), &m_cookie)); + } + + void DeviceLostHelper::StopWatchingCurrentDevice() + { + if (m_dxgiDevice) + { + // QI For the ID3D11Device4 interface. + auto d3dDevice{ m_dxgiDevice.as<::ID3D11Device4>() }; + + // Unregister from the device lost event. + ::CloseThreadpoolWait(m_onDeviceLostHandler); + d3dDevice->UnregisterDeviceRemoved(m_cookie); + + // Clear member variables. + m_onDeviceLostHandler = nullptr; + m_eventHandle.close(); + m_cookie = 0; + m_device = nullptr; + m_dxgiDevice = nullptr; + } + } + + void CALLBACK DeviceLostHelper::OnDeviceLost(PTP_CALLBACK_INSTANCE /* instance */, PVOID context, PTP_WAIT /* wait */, TP_WAIT_RESULT /* waitResult */) + { + // Get the DeviceLostHelper context object. + auto deviceLostHelper = reinterpret_cast(context); + + // Create a local reference to the old device before releasing the helper object's reference. + auto oldDevice = deviceLostHelper->m_device; + + // Stop listening for device lost events on the old device. + deviceLostHelper->StopWatchingCurrentDevice(); + + // Invoke the event handler. + deviceLostHelper->RaiseDeviceLostEvent(oldDevice); + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DeviceLostHelper.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DeviceLostHelper.h new file mode 100644 index 000000000..67f33431b --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DeviceLostHelper.h @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +namespace winrt::DrawingIslandComponents::implementation +{ + struct DeviceLostEventArgs + { + DeviceLostEventArgs(IDirect3DDevice const& device) : m_device(device) + { + } + + IDirect3DDevice Device() { return m_device; } + + private: + IDirect3DDevice m_device; + }; + + struct DeviceLostHelper + { + DeviceLostHelper() = default; + + ~DeviceLostHelper() + { + StopWatchingCurrentDevice(); + } + + // Not copyable or assignable. + DeviceLostHelper(DeviceLostHelper const&) = delete; + void operator=(DeviceLostHelper const&) = delete; + + void WatchDevice(winrt::com_ptr<::IDXGIDevice> const& dxgiDevice); + + void StopWatchingCurrentDevice(); + + void DeviceLost(winrt::delegate const& handler) + { + m_deviceLost = handler; + } + + private: + void RaiseDeviceLostEvent(IDirect3DDevice const& oldDevice) + { + m_deviceLost(this, DeviceLostEventArgs{ oldDevice }); + } + + static void CALLBACK OnDeviceLost(PTP_CALLBACK_INSTANCE /* instance */, PVOID context, PTP_WAIT /* wait */, TP_WAIT_RESULT /* waitResult */); + + private: + winrt::delegate m_deviceLost; + IDirect3DDevice m_device; + winrt::com_ptr<::IDXGIDevice> m_dxgiDevice; + PTP_WAIT m_onDeviceLostHandler{ nullptr }; + winrt::handle m_eventHandle; + DWORD m_cookie{ 0 }; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIsland.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIsland.cpp new file mode 100644 index 000000000..e45a62a35 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIsland.cpp @@ -0,0 +1,987 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include "DrawingIsland.h" +#include "DrawingIsland.g.cpp" + +namespace winrt::DrawingIslandComponents::implementation +{ + DrawingIsland::DrawingIsland( + const winrt::Compositor& compositor) + { + m_output.Compositor = compositor; + m_output.TextRenderer = std::make_shared(m_output.Compositor); + m_output.DeviceLostHelper.WatchDevice(m_output.TextRenderer->GetDevice()); + m_output.DeviceLostHelper.DeviceLost({ this, &DrawingIsland::OnDirect3DDeviceLost }); + + // Create the Compositor and the Content: + // - The Bridge's connection to the Window will keep everything alive, and perform an + // orderly tear-down: + // + // Window -> Bridge -> Content -> Visual -> InputSite -> InputObject + // + // - When the ContentIsland is destroyed, ContentIsland.AppData will call IClosable.Close + // on this instance to break cycles and clean up expensive resources. + + m_output.RootVisual = m_output.Compositor.CreateContainerVisual(); + m_output.RootVisual.RelativeSizeAdjustment({ 1.0f, 1.0f }); + + m_island = winrt::ContentIsland::Create(m_output.RootVisual); + m_island.AppData(get_strong().as()); + + Output_Initialize(); + Input_Initialize(); + Environment_Initialize(); + Accessibility_Initialize(); + + m_prevState.RasterizationScale = m_island.RasterizationScale(); + + // Get notifications for resize, bridge changes, etc. + (void)m_island.StateChanged( + [&](auto&& ...) + { + return Island_OnStateChanged(); + }); + + + (void)m_island.Closed( + [&]() + { + return Island_OnClosed(); + }); + + } + + + DrawingIsland::~DrawingIsland() + { + m_output.Compositor = nullptr; + } + + + void + DrawingIsland::Close() + { + m_output.RootVisual = nullptr; + + m_input.KeyboardSource = nullptr; + m_input.PretranslateSource = nullptr; + m_input.PointerSource = nullptr; + m_input.FocusController = nullptr; + + m_background.BrushDefault = nullptr; + m_background.BrushA = nullptr; + m_background.BrushB = nullptr; + m_background.BrushC = nullptr; + m_background.Visual = nullptr; + + m_items.Visuals = nullptr; + m_items.Items.clear(); + m_items.SelectedItem = nullptr; + + if (nullptr != m_background.BackdropController) + { + // Clean up our SystemBackdropController. + m_background.BackdropController.RemoveAllSystemBackdropTargets(); + m_background.BackdropController.Close(); + m_background.BackdropController = nullptr; + } + + if (nullptr != m_background.BackdropConfiguration) + { + m_background.BackdropConfiguration = nullptr; + } + + // Make sure automation is destroyed. + for (auto& automationPeer : m_uia.AutomationPeers) + { + automationPeer.GetAutomationProvider()->SetCallbackHandler(nullptr); + } + m_uia.AutomationPeers.clear(); + + if (nullptr != m_uia.FragmentRoot) + { + m_uia.FragmentRoot->SetCallbackHandler(nullptr); + m_uia.FragmentRoot = nullptr; + } + + + // Destroy Content: + // - This handles if the ContentIsland has already started destruction and is notifying the + // app. + + m_island.Close(); + m_island = nullptr; + + // TODO: Add the following test case in automated tests: + // 1. We are recursively calling ContentIsland.Close while inside the ContentIsland.Closed + // event. + // 2. We are testing the potential final Release() of ContentIsland while inside the Closed + // event. + + m_output.Compositor = nullptr; + } + + + void DrawingIsland::EnableBackgroundTransparency( + bool value) + { + if (value != m_background.BackdropEnabled) + { + m_background.BackdropEnabled = value; + Output_UpdateSystemBackdrop(); + } + } + + + IFACEMETHODIMP + DrawingIsland::OnDirectMessage( + IInputPreTranslateKeyboardSourceInterop* /*source*/, + const MSG* msg, + UINT keyboardModifiers, + _Inout_ bool* handled) + { + *handled = false; + + // Alt+A Debug print to see the order of the PreTranslate callbacks + if ((keyboardModifiers & FALT) && + (msg->message == WM_SYSKEYDOWN) && + (static_cast(msg->wParam) == winrt::VirtualKey::A)) + { + + } + + if (keyboardModifiers & FALT) + { + *handled = Input_AcceleratorKeyActivated( + static_cast(msg->wParam)); + } + + return S_OK; + } + + + IFACEMETHODIMP + DrawingIsland::OnTreeMessage( + IInputPreTranslateKeyboardSourceInterop* /*source*/, + const MSG* msg, + UINT keyboardModifiers, + _Inout_ bool* handled) + { + // Alt+A Debug print to see the order of the PreTranslate callbacks + if ((keyboardModifiers & FALT) && + (msg->message == WM_SYSKEYDOWN) && + (static_cast(msg->wParam) == winrt::VirtualKey::A)) + { + + } + + *handled = false; + return S_OK; + } + + + winrt::Windows::Graphics::RectInt32 + DrawingIsland::GetScreenBoundsForAutomationFragment( + _In_::IUnknown const* const sender) const + { + // Check if the automation provider that has sent this callback is the fragment root. + if (m_uia.FragmentRoot.as<::IUnknown>().get() == sender) + { + winrt::Rect logicalRect; + logicalRect.X = 0; + logicalRect.Y = 0; + logicalRect.Width = m_island.ActualSize().x; + logicalRect.Height = m_island.ActualSize().y; + + // This will convert from the logical coordinate space of the ContentIsland to + // Win32 screen coordinates that are needed by Accessibility. + return m_island.CoordinateConverter().ConvertLocalToScreen(logicalRect); + } + + // Else find the matching automation peer entry for the sending fragment. + auto iterator = std::find_if( + m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), + [&sender](auto const& automationPeer) + { + return automationPeer.Match(sender); + }); + + if (m_uia.AutomationPeers.end() == iterator) + { + // Did not find any match for this automation provider. + return { 0, 0, 0, 0 }; + } + + auto const& visualPeer = iterator->GetVisual(); + winrt::Rect logicalRect; + logicalRect.X = visualPeer.Offset().x; + logicalRect.Y = visualPeer.Offset().y; + logicalRect.Width = visualPeer.Size().x; + logicalRect.Height = visualPeer.Size().y; + + // This will convert from the logical coordinate space of the ContentIsland to + // Win32 screen coordinates that are needed by Accessibility. + return m_island.CoordinateConverter().ConvertLocalToScreen(logicalRect); + } + + + winrt::com_ptr + DrawingIsland::GetFragmentFromPoint( + _In_ double x, + _In_ double y) const + { + // UIA provides hit test points in screen space. + // Convert the point into a dummy empty rectangle to use with the coordinate converter. + winrt::Windows::Graphics::RectInt32 screenRect + { static_cast(x + 0.5), static_cast(y + 0.5), 0, 0 }; + + auto logicalRect = m_island.CoordinateConverter().ConvertScreenToLocal(screenRect); + float2 localPoint{ logicalRect.X, logicalRect.Y }; + auto hitTestElement = HitTestItem(localPoint); + + // Find the automation peer for the hit test visual if any. + if (nullptr != hitTestElement) + { + auto& hitTestVisual = hitTestElement->GetVisual(); + + auto iterator = std::find_if( + m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), + [&hitTestVisual](auto const& automationPeer) + { + return automationPeer.Match(hitTestVisual); + }); + + if (m_uia.AutomationPeers.end() != iterator) + { + // Return the automation provider if we found an automation peer + // for the hit test visual. + return iterator->GetAutomationProvider().as(); + } + } + + return nullptr; + } + + + winrt::com_ptr + DrawingIsland::GetFragmentInFocus() const + { + if (m_items.SelectedItem != nullptr) + { + auto& visual = m_items.SelectedItem->GetVisual(); + + // Find the currently selected visual's automation peer. + auto iterator = std::find_if( + m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), + [visual](auto const& automationPeer) + { + return automationPeer.Match(visual); + }); + + if (m_uia.AutomationPeers.end() != iterator) + { + // Return the automation provider if we found an automation peer + // for the selected visual. + return iterator->GetAutomationProvider().as(); + } + } + + return nullptr; + } + + + Item* DrawingIsland::HitTestItem(float2 const& point) const + { + // Iterate from the end of the vector, i.e., from front to back. + for (size_t i = m_items.Items.size(); i != 0; i--) + { + Item* item = m_items.Items[i - 1].get(); + auto& visual = item->GetVisual(); + + winrt::float3 const offset = visual.Offset(); + float2 const size = visual.Size(); + + if (point.x >= offset.x && + point.x < offset.x + size.x && + point.y >= offset.y && + point.y < offset.y + size.y) + { + return item; + } + } + return nullptr; + } + + + void + DrawingIsland::Accessibility_Initialize() + { + // Create an UI automation fragment root for our island's content. + m_uia.FragmentRoot = winrt::make_self(); + m_uia.FragmentRoot->SetName(L"Drawing Squares"); + m_uia.FragmentRoot->SetProviderOptions( + ProviderOptions_ServerSideProvider | + ProviderOptions_UseComThreading | + ProviderOptions_RefuseNonClientSupport); + m_uia.FragmentRoot->SetUiaControlTypeId(UIA_WindowControlTypeId); + m_uia.FragmentRoot->SetCallbackHandler(this); + + (void)m_island.AutomationProviderRequested( + { this, &DrawingIsland::Accessibility_OnAutomationProviderRequested }); + } + + + void + DrawingIsland::Accessibility_CreateItemFragment( + const winrt::Visual& itemVisual) + { + // Create a new automation fragment. + auto fragment = winrt::make_self(); + fragment->SetName(s_colorNames[m_output.CurrentColorIndex].c_str()); + fragment->SetCallbackHandler(this); + + // Add an entry to our automation peers (a mapping between the Visual and the Fragment): + // - This is keeping the UIA objects alive. + // - The lookup is used to get back to the item Fragment for + // specific operations, such as hit-testing or tree walking. + // This avoids adding to more expensive data storage, + // such as the Visual.CustomProperties map. + m_uia.AutomationPeers.push_back(AutomationPeer{ itemVisual, fragment }); + + // Connect the automation fragment to our fragment root. + m_uia.FragmentRoot->AddChildToEnd(fragment); + } + + + void + DrawingIsland::Accessibility_OnAutomationProviderRequested( + const winrt::ContentIsland& island, + const winrt::ContentIslandAutomationProviderRequestedEventArgs& args) + { + // Make sure the host provider is up to date. + m_uia.FragmentRoot->SetHostProvider( + island.GetAutomationHostProvider().as()); + + // Return the fragment root as an IInspectable. + args.AutomationProvider(m_uia.FragmentRoot.as()); + + args.Handled(true); + } + + + void + DrawingIsland::Input_Initialize() + { + m_input.PointerSource = winrt::InputPointerSource::GetForIsland(m_island); + + m_input.PointerSource.PointerPressed( + [this](winrt::InputPointerSource const&, + winrt::PointerEventArgs const& args) + { + auto currentPoint = args.CurrentPoint(); + auto properties = currentPoint.Properties(); + + if (properties.IsLeftButtonPressed()) + { + Input_OnLeftButtonPressed(args); + } + else if (properties.IsRightButtonPressed()) + { + Input_OnRightButtonPressed(args); + } + }); + + m_input.PointerSource.PointerMoved( + [this](winrt::InputPointerSource const&, + winrt::PointerEventArgs const& args) + { + Input_OnPointerMoved(args); + }); + + m_input.PointerSource.PointerReleased( + [&](auto&& ...) + { + Input_OnPointerReleased(); + }); + + // Set up the keyboard source. + m_input.KeyboardSource = winrt::InputKeyboardSource::GetForIsland(m_island); + + m_input.KeyboardSource.KeyDown( + [this](winrt::InputKeyboardSource const&, + winrt::KeyEventArgs const& args) + { + bool handled = Input_OnKeyDown(args.VirtualKey()); + + // Mark the event as handled + if (handled) + { + args.Handled(true); + } + }); + + m_input.PretranslateSource = + winrt::InputPreTranslateKeyboardSource::GetForIsland(m_island); + + m_input.PretranslateSource.as< + Microsoft::UI::Input::IInputPreTranslateKeyboardSourceInterop>()-> + SetPreTranslateHandler(this); + + auto activationListener = winrt::InputActivationListener::GetForIsland(m_island); + (void)activationListener.InputActivationChanged( + [this, activationListener]( + winrt::InputActivationListener const&, + winrt::InputActivationListenerActivationChangedEventArgs const&) + { + switch (activationListener.State()) + { + case winrt::InputActivationState::Activated: + m_output.RootVisual.Opacity(1.0f); + if (nullptr != m_background.BackdropConfiguration) + { + m_background.BackdropConfiguration.IsInputActive(true); + } + break; + + default: + m_output.RootVisual.Opacity(m_output.Opacity); + if (nullptr != m_background.BackdropConfiguration) + { + m_background.BackdropConfiguration.IsInputActive(false); + } + break; + } + }); + + m_input.FocusController = winrt::InputFocusController::GetForIsland(m_island); + m_input.FocusController.NavigateFocusRequested( + [this](winrt::InputFocusController const&, + winrt::FocusNavigationRequestEventArgs const& args) + { + bool setFocus = m_input.FocusController.TrySetFocus(); + // Mark the event as handled + if (setFocus) + { + args.Result(winrt::FocusNavigationResult::Moved); + } + }); + } + + + bool + DrawingIsland::Input_OnKeyDown( + winrt::Windows::System::VirtualKey virtualKey) + { + bool handled = false; + + switch (virtualKey) + { + case winrt::VirtualKey::A: + { + m_background.Visual.Brush(m_background.BrushA); + handled = true; + break; + } + + case winrt::VirtualKey::B: + { + m_background.Visual.Brush(m_background.BrushB); + handled = true; + break; + } + + case winrt::VirtualKey::C: + { + m_background.Visual.Brush(m_background.BrushC); + handled = true; + break; + } + + case winrt::VirtualKey::Space: + { + m_background.Visual.Brush(m_background.BrushDefault); + break; + } + + case winrt::Windows::System::VirtualKey::Number1: + { + m_output.CurrentColorIndex = 0; + handled = true; + break; + } + + case winrt::Windows::System::VirtualKey::Number2: + { + m_output.CurrentColorIndex = 1; + handled = true; + break; + } + + case winrt::Windows::System::VirtualKey::Number3: + { + m_output.CurrentColorIndex = 2; + handled = true; + break; + } + + case winrt::Windows::System::VirtualKey::Number4: + { + m_output.CurrentColorIndex = 3; + handled = true; + break; + } + + case winrt::Windows::System::VirtualKey::Delete: + case winrt::Windows::System::VirtualKey::Escape: + { + m_items.Visuals.RemoveAll(); + m_items.Items.clear(); + + // Update accessibility. + m_uia.FragmentRoot->RemoveAllChildren(); + m_uia.AutomationPeers.clear(); + + handled = true; + break; + } + + case winrt::Windows::System::VirtualKey::Tab: + { + auto request = winrt::Microsoft::UI::Input::FocusNavigationRequest::Create( + winrt::Microsoft::UI::Input::FocusNavigationReason::First); + m_input.FocusController.DepartFocus(request); + } + } + + Output_UpdateCurrentColorVisual(); + + return handled; + } + + bool + DrawingIsland::Input_AcceleratorKeyActivated( + winrt::Windows::System::VirtualKey virtualKey) + { + bool handled = false; + + switch (virtualKey) + { + case winrt::VirtualKey::X: + { + m_background.Visual.Brush(m_background.BrushA); + handled = true; + break; + } + + case winrt::VirtualKey::Y: + { + m_background.Visual.Brush(m_background.BrushB); + handled = true; + break; + } + + case winrt::VirtualKey::Z: + { + m_background.Visual.Brush(m_background.BrushC); + handled = true; + break; + } + } + + return handled; + } + + + void + DrawingIsland::Input_OnLeftButtonPressed( + const winrt::PointerEventArgs& args) + { + // Left button manipulates the custom-drawn content + float2 const point = args.CurrentPoint().Position(); + + bool controlPressed = WI_IsFlagSet( + args.KeyModifiers(), + winrt::Windows::System::VirtualKeyModifiers::Control); + + OnLeftClick(point, controlPressed); + } + + + void + DrawingIsland::Input_OnPointerReleased() + { + m_items.SelectedItem = nullptr; + } + + + void + DrawingIsland::LeftClickAndRelease( + const float2 currentPoint) + { + OnLeftClick(currentPoint, false); + Input_OnPointerReleased(); + } + + + void + DrawingIsland::RightClickAndRelease( + const float2 currentPoint) + { + OnRightClick(currentPoint); + Input_OnPointerReleased(); + } + + + void + DrawingIsland::OnLeftClick( + const float2 point, + bool controlPressed) + { + m_items.SelectedItem = HitTestItem(point); + + if (m_items.SelectedItem != nullptr) + { + Item* item = m_items.SelectedItem; + auto& visual = m_items.SelectedItem->GetVisual(); + winrt::float3 const offset = visual.Offset(); + + m_items.Offset.x = offset.x - point.x; + m_items.Offset.y = offset.y - point.y; + + // Move the visual to the top. + m_items.Visuals.Remove(visual); + m_items.Visuals.InsertAtTop(visual); + + // Move the VisualElement to the end of the vector if it isn't already. + if (!m_items.Items.empty() && m_items.Items.back().get() != item) + { + auto i = std::find_if( + m_items.Items.begin(), + m_items.Items.end(), + [item](auto& elem) { return elem.get() == item; } + ); + if (i != m_items.Items.end()) + { + std::rotate(i, i + 1, m_items.Items.end()); + } + } + + // Update automation. + // First find the existing automation peer. + auto iterator = std::find_if( + m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), + [visual](auto const& automationPeer) + { + return automationPeer.Match(visual); + }); + if (m_uia.AutomationPeers.end() != iterator) + { + // Mirror the change to the visuals above. + m_uia.FragmentRoot->RemoveChild(iterator->GetAutomationProvider()); + m_uia.FragmentRoot->AddChildToEnd(iterator->GetAutomationProvider()); + } + } + else + { + Output_AddVisual(point, controlPressed); + } + } + + + void + DrawingIsland::Input_OnRightButtonPressed( + const winrt::PointerEventArgs& args) + { + OnRightClick(args.CurrentPoint().Position()); + } + + void + DrawingIsland::OnRightClick(const float2 point) + { + // TODO - what is the purpose of this? + UNREFERENCED_PARAMETER(point); + // auto selectedVisual = HitTestVisual(point); + } + + void + DrawingIsland::Input_OnPointerMoved( + const winrt::PointerEventArgs& args) + { + if (m_items.SelectedItem) + { + auto& visual = m_items.SelectedItem->GetVisual(); + float2 const point = args.CurrentPoint().Position(); + + visual.Offset( + { point.x + m_items.Offset.x, + point.y + m_items.Offset.y, + 0.0f }); + } + } + + + void + DrawingIsland::Island_OnClosed() + { + + } + + + void + DrawingIsland::Island_OnStateChanged() + { + if (m_prevState.RasterizationScale != m_island.RasterizationScale()) + { + float newScale = m_island.RasterizationScale(); + + m_prevState.RasterizationScale = newScale; + + m_output.TextRenderer->SetDpiScale(newScale); + + for (auto& item : m_items.Items) + { + item->OnDpiScaleChanged(); + } + } + + if (m_prevState.LayoutDirection != m_island.LayoutDirection()) + { + Environment_SetLayoutDirection(); + } + + Output_UpdateCurrentColorVisual(); + } + + + void + DrawingIsland::Environment_SetLayoutDirection() + { + if (m_island.LayoutDirection() == ContentLayoutDirection::RightToLeft) + { + // The following will mirror the visuals. If any text is inside the visuals the text is + // also mirrored. The text will need another RelativeOffsetAdjustment and Scale to + // return to the normal space. + + m_output.RootVisual.RelativeOffsetAdjustment(winrt::float3(1, 0, 0)); + m_output.RootVisual.Scale(winrt::float3(-1, 1, 1)); + } + else + { + m_output.RootVisual.RelativeOffsetAdjustment(winrt::float3(0, 0, 0)); + m_output.RootVisual.Scale(winrt::float3(1, 1, 1)); + } + m_prevState.LayoutDirection = m_island.LayoutDirection(); + } + + + void + DrawingIsland::OnDirect3DDeviceLost( + DeviceLostHelper const* /* sender */, + DeviceLostEventArgs const& /* args */) + { + // This call comes in on a Threadpool worker thread, so use the DispatcherQueue + // to marshal the call to the UI thread. + m_island.DispatcherQueue().TryEnqueue( + [this] { + // Recreate the text renderer's D3D and D2D devices. + m_output.TextRenderer->RecreateDirect2DDevice(); + + // Give each item an opportunity to recreate its device-dependent resources. + for (auto& item : m_items.Items) + { + item->OnDeviceLost(); + } + + // Listen for device lost on the new device. + m_output.DeviceLostHelper.WatchDevice(m_output.TextRenderer->GetDevice()); + }); + } + + + void + DrawingIsland::Output_Initialize() + { + // Create the background visual. + m_background.Visual = m_output.Compositor.CreateSpriteVisual(); + m_background.Visual.RelativeSizeAdjustment({ 1.0f, 1.0f }); + + m_background.BrushDefault = m_output.Compositor.CreateColorBrush( + winrt::Color{ 0xFF, 0x20, 0x20, 0x20 }); + + m_background.BrushA = m_output.Compositor.CreateColorBrush( + winrt::Color{ 0xFF, 0x99, 0x20, 0x20 }); + + m_background.BrushB = m_output.Compositor.CreateColorBrush( + winrt::Color{ 0xFF, 0x20, 0x99, 0x20 }); + + m_background.BrushC = m_output.Compositor.CreateColorBrush( + winrt::Color{ 0xFF, 0x20, 0x20, 0x99 }); + + m_background.Visual.Brush(m_background.BrushDefault); + m_output.RootVisual.Children().InsertAtTop(m_background.Visual); + + for (int i = 0; i < _countof(m_output.ColorBrushes); i++) + { + m_output.ColorBrushes[i] = m_output.Compositor.CreateColorBrush(s_colors[i]); + + winrt::Color halfTransparent = s_colors[i]; + halfTransparent.A = 0x80; + m_output.HalfTransparentColorBrushes[i] = + m_output.Compositor.CreateColorBrush(halfTransparent); + } + + winrt::ContainerVisual drawingVisualsRoot = m_output.Compositor.CreateContainerVisual(); + m_items.Visuals = drawingVisualsRoot.Children(); + m_output.RootVisual.Children().InsertAtTop(drawingVisualsRoot); + + m_items.CurrentColorVisual = m_output.Compositor.CreateSpriteVisual(); + m_items.CurrentColorVisual.Offset({0.0f, 0.0f, 0.0f}); + m_output.RootVisual.Children().InsertAtTop(m_items.CurrentColorVisual); + + Output_UpdateSystemBackdrop(); + + Output_UpdateCurrentColorVisual(); + } + + + void + DrawingIsland::Output_AddVisual( + float2 const point, + bool halfTransparent) + { + // Determine the visual background and text colors. + Color backgroundColor = s_colors[m_output.CurrentColorIndex]; + Color textColor = { 0xFF, 0, 0, 0 }; + if (halfTransparent) + { + backgroundColor.A /= 2; + textColor.A /= 2; + } + + // Create a TextElement object. + auto textItem = std::make_unique( + m_output.TextRenderer, + backgroundColor, + textColor, + s_colorNames[m_output.CurrentColorIndex] + ); + + // Get the visual and its size in DIPs. + auto& visual = textItem->GetVisual(); + float2 size = visual.Size(); + + // Set the visual's offset. + visual.Offset({ point.x - size.x / 2.0f, point.y - size.y / 2.0f, 0.0f }); + + // Add the new text element to the vector. + m_items.Items.push_back(std::move(textItem)); + + // Add the visual as a child of the container visual. + m_items.Visuals.InsertAtTop(visual); + + m_items.SelectedItem = m_items.Items.back().get(); + m_items.Offset.x = -size.x / 2.0f; + m_items.Offset.y = -size.y / 2.0f; + + Accessibility_CreateItemFragment(visual); + } + + + void + DrawingIsland::Output_UpdateCurrentColorVisual() + { + m_items.CurrentColorVisual.Brush(m_output.ColorBrushes[m_output.CurrentColorIndex]); + m_items.CurrentColorVisual.Offset({0.0f, m_island.ActualSize().y - 25.0f, 0.0f}); + m_items.CurrentColorVisual.Size({m_island.ActualSize().x, 25.0f}); + } + + + void + DrawingIsland::Output_UpdateSystemBackdrop() + { + if (m_background.BackdropEnabled && nullptr == m_background.BackdropController) + { + // Reduce the opacity of the background color visual so that we can see + // the Mica/DesktopAcrylic behind it. + m_background.Visual.Opacity(0.1f); + + // Create a new SystemBackdropConfiguration if we do not already have one. + if (nullptr == m_background.BackdropConfiguration) + { + m_background.BackdropConfiguration = winrt::SystemBackdropConfiguration(); + } + + // Decide between Mica and DesktopAcrylic. + if (winrt::MicaController::IsSupported()) + { + m_background.BackdropController = winrt::MicaController(); + + } + else + { + m_background.BackdropController = winrt::DesktopAcrylicController(); + } + + // Link the SystemBackdropConfiguration to our SystemBackdropController. + m_background.BackdropController.SetSystemBackdropConfiguration( + m_background.BackdropConfiguration); + + // Add our island as the target. + m_background.BackdropController.AddSystemBackdropTarget(m_island); + } + else + { + // Reset the background opacity to 1.0 + m_background.Visual.Opacity(1.0f); + + if (nullptr != m_background.BackdropController) + { + // Clean up our SystemBackdropController. + m_background.BackdropController.RemoveAllSystemBackdropTargets(); + m_background.BackdropController.Close(); + m_background.BackdropController = nullptr; + } + } + } + + void + DrawingIsland::Environment_Initialize() + { + auto window = m_island.Environment(); + + (void)window.SettingChanged( + [this](winrt::ContentIslandEnvironment const&, + winrt::ContentEnvironmentSettingChangedEventArgs const& args) + { + return Environment_OnSettingChanged(args); + }); + + (void)window.StateChanged( + [this](winrt::ContentIslandEnvironment const& sender, winrt::IInspectable const&) + { + return Environment_OnStateChanged(sender); + }); + } + + + void + DrawingIsland::Environment_OnSettingChanged( + const winrt::ContentEnvironmentSettingChangedEventArgs& args) + { + auto settingChanged = args.SettingName(); + + if (settingChanged == L"intl") + { + m_background.Visual.Brush(m_background.BrushA); + } + } + + + void + DrawingIsland::Environment_OnStateChanged(winrt::ContentIslandEnvironment const& /*sender*/) + { + + } +} // namespace winrt::OneTest::ContentIslandHelpers::implementation diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIsland.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIsland.h new file mode 100644 index 000000000..a1924001f --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIsland.h @@ -0,0 +1,300 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +#include "DrawingIsland.g.h" +#include "AutomationFragmentRoot.h" +#include "AutomationPeer.h" +#include "TextRenderer.h" +#include "DeviceLostHelper.h" +#include "TextItem.h" + +namespace winrt::DrawingIslandComponents::implementation +{ + struct DrawingIsland : + public DrawingIslandT< + DrawingIsland, + Microsoft::UI::Input::IInputPreTranslateKeyboardSourceHandler>, + IAutomationCallbackHandler + { + public: + // Construction + + DrawingIsland( + const winrt::Compositor& compositor); + + ~DrawingIsland(); + + // IClosable methods + void Close(); + + // Properties + + bool EnableBackgroundTransparency() + { + return m_background.BackdropEnabled; + } + + void EnableBackgroundTransparency( + bool value); + + winrt::ContentIsland Island() const + { + return m_island; + } + + // Methods + + void LeftClickAndRelease( + const float2 currentPoint); + + void RightClickAndRelease( + const float2 currentPoint); + + void SetIslandOpacity(float islandOpacity) + { + m_output.Opacity = islandOpacity; + } + + void SetColorIndex(std::uint32_t colorIndex) + { + m_output.CurrentColorIndex = std::clamp( + colorIndex, 0, _countof(s_colors) - 1); + + if (m_output.CurrentColorIndex >= 4) + { + m_background.BrushDefault = + m_output.Compositor.CreateColorBrush(s_colors[m_output.CurrentColorIndex]); + + m_background.Visual.Brush(m_background.BrushDefault); + } + Output_UpdateCurrentColorVisual(); + } + + // IInputKeyboardSourcePreTranslateHandler methods + IFACEMETHOD(OnDirectMessage)( + IInputPreTranslateKeyboardSourceInterop* source, + const MSG* msg, + UINT keyboardModifiers, + _Inout_ bool* handled); + + IFACEMETHOD(OnTreeMessage)( + IInputPreTranslateKeyboardSourceInterop* source, + const MSG* msg, + UINT keyboardModifiers, + _Inout_ bool* handled); + + // IAutomationCallbackHandler overrides. + winrt::Windows::Graphics::RectInt32 GetScreenBoundsForAutomationFragment( + _In_::IUnknown const* const sender) const override; + + winrt::com_ptr GetFragmentFromPoint( + _In_ double x, + _In_ double y) const override; + + winrt::com_ptr GetFragmentInFocus() const override; + + private: + Item* HitTestItem(float2 const& point) const; + + void Accessibility_Initialize(); + + void Accessibility_CreateItemFragment( + const winrt::Visual& itemVisual); + + void Accessibility_OnAutomationProviderRequested( + const winrt::ContentIsland& island, + const winrt::ContentIslandAutomationProviderRequestedEventArgs& args); + + void Input_Initialize(); + + bool Input_OnKeyDown( + winrt::Windows::System::VirtualKey virtualKey); + + bool Input_AcceleratorKeyActivated( + winrt::Windows::System::VirtualKey virtualKey); + + void Input_OnLeftButtonPressed( + const winrt::PointerEventArgs& args); + + void Input_OnRightButtonPressed( + const winrt::PointerEventArgs& args); + + void Input_OnPointerMoved( + const winrt::PointerEventArgs& args); + + void Input_OnPointerReleased(); + + void OnLeftClick( + const float2 point, + bool controlPressed); + + void OnRightClick( + const float2 currentPoint); + + void Island_OnClosed(); + + void Island_OnStateChanged(); + + void OnDirect3DDeviceLost( + DeviceLostHelper const* /* sender */, + DeviceLostEventArgs const& /* args */); + + void Output_Initialize(); + + void Output_AddVisual( + const float2 point, + bool halfTransparent); + + void Output_UpdateCurrentColorVisual(); + + void Output_UpdateSystemBackdrop(); + + void Environment_Initialize(); + + void Environment_OnSettingChanged( + const winrt::ContentEnvironmentSettingChangedEventArgs& args); + + void Environment_OnStateChanged(winrt::ContentIslandEnvironment const& sender); + + void Environment_SetLayoutDirection(); + + private: + static inline winrt::Color s_colors[] = + { + { 0xFF, 0x5B, 0x9B, 0xD5 }, + { 0xFF, 0xED, 0x7D, 0x31 }, + { 0xFF, 0x70, 0xAD, 0x47 }, + { 0xFF, 0xFF, 0xC0, 0x00 }, + { 0xFF, 0xFA, 0xEB, 0xD7 }, + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFA, 0xFA }, + { 0xFF, 0xFF, 0xC0, 0xCB }, + { 0xFF, 0xB0, 0xE0, 0xE6 }, + { 0xFF, 0x98, 0xFB, 0x98 }, + { 0xFF, 0x87, 0xCE, 0xFA }, + }; + + static inline std::wstring s_colorNames[] = + { + L"Blue", + L"Orange", + L"Green", + L"Yellow", + L"AntiqueWhite", + L"White", + L"Snow", + L"Pink", + L"PowderBlue", + L"PaleGreen", + L"LightSkyBlue", + }; + + // The underlying Island holding everything together. + winrt::ContentIsland m_island{ nullptr }; + + // Output + struct + { + winrt::Compositor Compositor{ nullptr }; + + winrt::ContainerVisual RootVisual{ nullptr }; + + std::shared_ptr TextRenderer; + DeviceLostHelper DeviceLostHelper; + + float Opacity{ 0.5f }; + + // Current color used for new items + unsigned int CurrentColorIndex = 0; + + // Cached brushes for items + winrt::CompositionColorBrush ColorBrushes[_countof(s_colors)] + { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr }; + + winrt::CompositionColorBrush HalfTransparentColorBrushes[_countof(s_colors)] + { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr }; + } m_output; + + // Input handling + struct + { + // Keyboard input handling + winrt::InputKeyboardSource KeyboardSource{ nullptr }; + + // Message loop integration + winrt::InputPreTranslateKeyboardSource PretranslateSource{ nullptr }; + + // Spatial input handling (mouse, pen, touch, etc.) + winrt::InputPointerSource PointerSource{ nullptr }; + + // Focus navigation handling + winrt::InputFocusController FocusController{ nullptr }; + } m_input; + + // Background behind the items + struct Background + { + winrt::CompositionColorBrush BrushDefault{ nullptr }; + winrt::CompositionColorBrush BrushA{ nullptr }; + winrt::CompositionColorBrush BrushB{ nullptr }; + winrt::CompositionColorBrush BrushC{ nullptr }; + winrt::SpriteVisual Visual{ nullptr }; + winrt::RectangleClip Clip{ nullptr }; + + // System backdrops (Mica on Win11+, DesktopAcrylic on Win10) + bool BackdropEnabled{ true }; + winrt::SystemBackdropConfiguration BackdropConfiguration{ nullptr }; + winrt::ISystemBackdropControllerWithTargets BackdropController{ nullptr }; + } m_background; + + // Drawing items being manipulated. + struct + { + // The container visual's Children collection. Each Item's visual must be + // added to this collection to be rendered. + winrt::VisualCollection Visuals{ nullptr }; + + // Vector of Item objects representing items that can be manipulated, in + // back-to-front order. Each item has an associated Visual. + std::vector> Items; + + // Pointer to the currently-selected item, if any. + Item* SelectedItem{ nullptr }; + + // Offset from the top-left corner of the selected item to the pointer. + float2 Offset{}; + + // Visual that shows the current color. + winrt::SpriteVisual CurrentColorVisual{ nullptr }; + } m_items; + + struct + { + float RasterizationScale = 0; + + winrt::ContentLayoutDirection LayoutDirection = + winrt::ContentLayoutDirection::LeftToRight; + } m_prevState; + + struct + { + // The UIA parent Root for this Island that contains the fragment children. + winrt::com_ptr FragmentRoot{ nullptr }; + + // Map a given square (Visual) to its UIA fragment object. + std::vector AutomationPeers{}; + } m_uia; + }; +} + +namespace winrt::DrawingIslandComponents::factory_implementation +{ + struct DrawingIsland : + DrawingIslandT + { + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.def b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.def new file mode 100644 index 000000000..24e7c1235 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj new file mode 100644 index 000000000..8fa5e8bb5 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj @@ -0,0 +1,188 @@ + + + + + + + true + true + true + true + {709c54e1-0f2f-4a59-80b2-4cfd08b720e5} + DrawingIslandComponents + DrawingIslandComponents + en-US + 14.0 + 10.0.22621.0 + 10.0.17134.0 + true + C++/WinRT + + + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + DynamicLibrary + v143 + v142 + v141 + v140 + Unicode + false + + + true + true + + + false + true + false + + + true + + + true + + + true + + + true + + + true + + + true + + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + false + DrawingIslandComponents.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + + + + + + Components.idl + + + + + + + + + + + Create + + + Components.idl + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj.filters b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj.filters new file mode 100644 index 000000000..8d5d319bd --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj.filters @@ -0,0 +1,83 @@ + + + + + accd3aa8-1ba0-4223-9bbe-0c431709210b + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {926ab91d-31b4-48c3-b9a4-e681349f27f0} + + + {d824b7c5-294e-46a7-ae4e-2d146beef954} + + + {23c94a0e-e18d-4439-9afc-234fafb5cfcb} + + + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/Item.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/Item.cpp new file mode 100644 index 000000000..4e28b475e --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/Item.cpp @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include "Item.h" + +namespace winrt::DrawingIslandComponents::implementation +{ + Item::Item(winrt::Compositor const& compositor) : + m_visual(compositor.CreateSpriteVisual()) + { + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/Item.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/Item.h new file mode 100644 index 000000000..14d8a7569 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/Item.h @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +namespace winrt::DrawingIslandComponents::implementation +{ + // Abstract base class for an item that owns a SpriteVisual and can + // re-rasterize the sprite if the DPI changes. + class Item + { + public: + Item(winrt::Compositor const& compositor); + + virtual ~Item() + { + } + + virtual void OnDpiScaleChanged() + { + } + + virtual void OnDeviceLost() + { + } + + winrt::SpriteVisual const& GetVisual() const noexcept + { + return m_visual; + } + + private: + winrt::SpriteVisual m_visual; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/PropertySheet.props b/Samples/Islands/DrawingIsland/DrawingIslandComponents/PropertySheet.props new file mode 100644 index 000000000..e34141b01 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextItem.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextItem.cpp new file mode 100644 index 000000000..823c4469c --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextItem.cpp @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include "TextItem.h" + +namespace winrt::DrawingIslandComponents::implementation +{ + TextItem::TextItem( + std::shared_ptr const& textRenderer, + Windows::UI::Color backgroundColor, + Windows::UI::Color textColor, + std::wstring const& text) : + Item(textRenderer->GetCompositor()), + m_textRenderer(textRenderer), + m_backgroundColor(backgroundColor), + m_textColor(textColor), + m_text(text) + { + InitializeVisual(); + } + + void TextItem::InitializeVisual() + { + // Render the text to the sprite visual. + m_textRenderer->Render(m_text.c_str(), m_backgroundColor, m_textColor, GetVisual()); + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextItem.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextItem.h new file mode 100644 index 000000000..e0754bf4a --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextItem.h @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +#include "TextRenderer.h" +#include "Item.h" + +namespace winrt::DrawingIslandComponents::implementation +{ + class TextItem final : public Item + { + public: + TextItem( + std::shared_ptr const& textRenderer, + Windows::UI::Color backgroundColor, + Windows::UI::Color textColor, + std::wstring const& text); + + void OnDpiScaleChanged() override + { + // Re-render the text using the current DPI scale. + InitializeVisual(); + } + + void OnDeviceLost() override + { + // Re-render the text using the current device. + InitializeVisual(); + } + + private: + void InitializeVisual(); + + std::shared_ptr m_textRenderer; + Windows::UI::Color m_backgroundColor; + Windows::UI::Color m_textColor; + std::wstring m_text; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextRenderer.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextRenderer.cpp new file mode 100644 index 000000000..16e51d06b --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextRenderer.cpp @@ -0,0 +1,208 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include "TextRenderer.h" + +namespace winrt::DrawingIslandComponents::implementation +{ + TextRenderer::TextRenderer(winrt::Compositor compositor) : m_compositor(compositor) + { + // Create the DWrite factory object. + winrt::check_hresult(DWriteCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(decltype(*m_dwriteFactory)), + reinterpret_cast<::IUnknown**>(m_dwriteFactory.put()))); + + // Create an object that encapsulates text formatting properties. + constexpr float defaultFontSize = 16; + winrt::check_hresult(m_dwriteFactory->CreateTextFormat( + L"Segoe UI", + nullptr, + DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + defaultFontSize, + L"en-US", + m_textFormat.put())); + winrt::check_hresult(m_textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP)); + + // Create the D2D factory. + winrt::check_hresult(D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, m_d2dFactory.put())); + + // Create the Direct3D and Direct2D device objects. + CreateDirect2DDevice(); + + // Create the composition graphics device. + auto compositorInterop = m_compositor.as(); + ICompositionGraphicsDevice compositionGraphicsDevice; + winrt::check_hresult(compositorInterop->CreateGraphicsDevice(m_d2dDevice.get(), &compositionGraphicsDevice)); + m_compositionGraphicsDevice = compositionGraphicsDevice.as(); + } + + void TextRenderer::RecreateDirect2DDevice() + { + // Release the old Direct2D and Direct2D device objects. + m_dxgiDevice = nullptr; + m_d2dDevice = nullptr; + + // Create new Direct3D and Direct2D device objects. + CreateDirect2DDevice(); + + // Restore the composition graphics device to health by pointing to the new Direct2D device. + auto compositionGraphicsDeviceInterop = m_compositionGraphicsDevice.as(); + winrt::check_hresult(compositionGraphicsDeviceInterop->SetRenderingDevice(m_d2dDevice.get())); + } + + void TextRenderer::CreateDirect2DDevice() + { + uint32_t createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; + + // Array with DirectX hardware feature levels in order of preference. + static const D3D_FEATURE_LEVEL featureLevels[] = + { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; + + // Create the Direct3D 11 API device object and a corresponding context. + winrt::com_ptr<::ID3D11Device> d3dDevice; + winrt::com_ptr<::ID3D11DeviceContext> d3dImmediateContext; + D3D_FEATURE_LEVEL d3dFeatureLevel{ D3D_FEATURE_LEVEL_9_1 }; + + winrt::check_hresult(D3D11CreateDevice( + nullptr, // Default adapter. + D3D_DRIVER_TYPE_HARDWARE, + 0, // Not asking for a software driver, so not passing a module to one. + createDeviceFlags, // Set debug and Direct2D compatibility flags. + featureLevels, + ARRAYSIZE(featureLevels), + D3D11_SDK_VERSION, + d3dDevice.put(), + &d3dFeatureLevel, + d3dImmediateContext.put())); + + // Initialize Direct2D resources. + D2D1_FACTORY_OPTIONS d2d1FactoryOptions{ D2D1_DEBUG_LEVEL_NONE }; + + // Create the Direct2D device object. + // Obtain the underlying DXGI device of the Direct3D device. + auto dxgiDevice = d3dDevice.as<::IDXGIDevice>(); + + winrt::com_ptr d2dDevice; + winrt::check_hresult(m_d2dFactory->CreateDevice(dxgiDevice.get(), d2dDevice.put())); + + // Save the newly-created objects. + m_dxgiDevice = std::move(dxgiDevice); + m_d2dDevice = std::move(d2dDevice); + } + + void TextRenderer::Render( + _In_z_ WCHAR const* text, + Windows::UI::Color backgroundColor, + Windows::UI::Color textColor, + SpriteVisual const& visual) + { + // Margins between the layout bounds of the text and the edges of the visual. + // These are in device-independent pixels (DIPs). + constexpr float marginLeft = 5; + constexpr float marginRight = 5; + constexpr float marginTop = 5; + constexpr float marginBottom = 5; + + // Create the IDWriteTextlayout object. This will be used to render the text + // and can also be used to get properties, such as the size. + winrt::com_ptr textLayout; + winrt::check_hresult(m_dwriteFactory->CreateTextLayout( + text, + static_cast(wcslen(text)), + m_textFormat.get(), + /*maxWidth*/ 0, + /*maxHeight*/ 0, + /*out*/ textLayout.put())); + + // Get the metrics from the text layout. + DWRITE_TEXT_METRICS textMetrics; + winrt::check_hresult(textLayout->GetMetrics(/*out*/ &textMetrics)); + + // Compute the size of the drawing surface in pixels. + // This is the text size plus margins, multiplied by the DPI scale and rounded up. + const float pixelWidth = ceilf((textMetrics.width + (marginLeft + marginRight)) * m_dpiScale); + const float pixelHeight = ceilf((textMetrics.height + (marginTop + marginBottom)) * m_dpiScale); + + try + { + // Create a composition surface to draw to. + CompositionDrawingSurface drawingSurface = m_compositionGraphicsDevice.CreateDrawingSurface( + Size(pixelWidth, pixelHeight), + winrt::Microsoft::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized, + winrt::Microsoft::Graphics::DirectX::DirectXAlphaMode::Premultiplied); + auto drawingSurfaceInterop = drawingSurface.as(); + + // Begin drawing to get a Direct2D device context. + winrt::com_ptr deviceContext; + POINT pixelOffset; + winrt::check_hresult(drawingSurfaceInterop->BeginDraw( + nullptr, + __uuidof(ID2D1DeviceContext), + deviceContext.put_void(), + &pixelOffset)); + + // Set the DPI of the device context, where 96 DPI corresponds to a 1.0 scale factor. + deviceContext->SetDpi(m_dpiScale * 96, m_dpiScale * 96); + + // Compute the origin (top-left corner) of the text layout in DIPs by converting + // the drawing surface offset from pixels to DIPs and adding the margin. + D2D_POINT_2F origin{ + pixelOffset.x / m_dpiScale + marginLeft, + pixelOffset.y / m_dpiScale + marginTop }; + + // Clear the background and draw the text. + deviceContext->Clear(ToColorF(backgroundColor)); + + // Use ClearType antialiasing if rendering onto an opaque background. + // Otherwise use grayscale. + deviceContext->SetTextAntialiasMode( + backgroundColor.A == 255 ? + D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE : + D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); + + // Create the brush used to fill the text. + winrt::com_ptr textBrush; + winrt::check_hresult(deviceContext->CreateSolidColorBrush(ToColorF(textColor), textBrush.put())); + + // Draw the text layout object. + deviceContext->DrawTextLayout(origin, textLayout.get(), textBrush.get()); + + // End drawing. + winrt::check_hresult(drawingSurfaceInterop->EndDraw()); + + // Create the surface brush and set it as the visual's brush. + auto surfaceBrush = m_compositor.CreateSurfaceBrush(); + surfaceBrush.Surface(drawingSurface); + visual.Brush(surfaceBrush); + + // Set the visual size to match the surface size (but in DIPs rather than pixels). + // This ensures there is no scaling. + visual.Size(Size(pixelWidth / m_dpiScale, pixelHeight / m_dpiScale)); + + // Ensure the visual is snapped to a pixel boundary. + visual.IsPixelSnappingEnabled(true); + } + catch (winrt::hresult_error& e) + { + // Silently ignore device-removed error. + // We'll draw again after the device is recreated. + if (e.code() == DXGI_ERROR_DEVICE_REMOVED) + return; + + // Rethrow all other exceptions. + throw; + } + } +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextRenderer.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextRenderer.h new file mode 100644 index 000000000..d05072d5a --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/TextRenderer.h @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +namespace winrt::DrawingIslandComponents::implementation +{ + class TextRenderer final + { + public: + TextRenderer(winrt::Compositor compositor); + + void SetDpiScale(float scale) + { + m_dpiScale = scale; + } + + void Render( + _In_z_ WCHAR const* text, + Windows::UI::Color backgroundColor, + Windows::UI::Color textColor, + SpriteVisual const& visual); + + winrt::Compositor const& GetCompositor() const noexcept + { + return m_compositor; + } + + winrt::com_ptr<::IDXGIDevice> const& GetDevice() const noexcept + { + return m_dxgiDevice; + } + + void RecreateDirect2DDevice(); + + private: + static inline D2D_COLOR_F ToColorF(Windows::UI::Color color) + { + return D2D_COLOR_F{ color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f }; + } + + void CreateDirect2DDevice(); + + winrt::Compositor m_compositor; + + // Device-independent resources. + winrt::com_ptr<::IDWriteFactory7> m_dwriteFactory; + winrt::com_ptr<::IDWriteTextFormat> m_textFormat; + winrt::com_ptr<::ID2D1Factory7> m_d2dFactory; + + // Device-dependent resources. + winrt::com_ptr<::IDXGIDevice> m_dxgiDevice; + winrt::com_ptr<::ID2D1Device6> m_d2dDevice; + CompositionGraphicsDevice m_compositionGraphicsDevice{ nullptr }; + + float m_dpiScale = 1.0f; + }; +} diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/packages.config b/Samples/Islands/DrawingIsland/DrawingIslandComponents/packages.config new file mode 100644 index 000000000..c4397c325 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/pch.cpp b/Samples/Islands/DrawingIsland/DrawingIslandComponents/pch.cpp new file mode 100644 index 000000000..40e691ba7 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/pch.cpp @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/pch.h b/Samples/Islands/DrawingIsland/DrawingIslandComponents/pch.h new file mode 100644 index 000000000..f15602e4b --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/pch.h @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +// Windows Platform Win32 +#include +#include +#include +#include + +// DWriteWrite and Direct2D for rendering text +#include +#include +#include +#include + +// WIL +#include +#include +#include + +// Windows Platform WinRT +#include +#include +#include +#include +#include +#include +#include + +// Windows App SDK +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include + +namespace winrt +{ + using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Foundation::Collections; + using namespace winrt::Windows::Foundation::Numerics; + using namespace winrt::Windows::Graphics::DirectX; + using namespace winrt::Windows::Graphics::DirectX::Direct3D11; + using namespace winrt::Windows::System; + using namespace winrt::Windows::UI; + + using namespace winrt::Microsoft::UI; + using namespace winrt::Microsoft::UI::Composition; + using namespace winrt::Microsoft::UI::Composition::SystemBackdrops; + using namespace winrt::Microsoft::UI::Content; + using namespace winrt::Microsoft::UI::Dispatching; + using namespace winrt::Microsoft::UI::Input; + using namespace winrt::Microsoft::UI::Windowing; +} + +using namespace Windows::Foundation::Numerics; diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/readme.txt b/Samples/Islands/DrawingIsland/DrawingIslandComponents/readme.txt new file mode 100644 index 000000000..f269f729f --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/readme.txt @@ -0,0 +1,23 @@ +======================================================================== + C++/WinRT DrawingIslandComponent Project Overview +======================================================================== + +This project demonstrates how to get started authoring Windows Runtime +classes directly with standard C++, using the C++/WinRT SDK component +to generate implementation headers from interface (IDL) files. The +generated Windows Runtime component binary and WinMD files should then +be bundled with the Universal Windows Platform (UWP) app consuming them. + +Steps: +1. Create an interface (IDL) file to define your Windows Runtime class, + its default interface, and any other interfaces it implements. +2. Build the project once to generate module.g.cpp, module.h.cpp, and + implementation templates under the "Generated Files" folder, as + well as skeleton class definitions under "Generated Files\sources". +3. Use the skeleton class definitions for reference to implement your + Windows Runtime classes. + +======================================================================== +Learn more about C++/WinRT here: +http://aka.ms/cppwinrt/ +======================================================================== diff --git a/Samples/Islands/DrawingIsland/DrawingIslandCsProjection/DrawingIslandCsProjection.csproj b/Samples/Islands/DrawingIsland/DrawingIslandCsProjection/DrawingIslandCsProjection.csproj new file mode 100644 index 000000000..a3c544e91 --- /dev/null +++ b/Samples/Islands/DrawingIsland/DrawingIslandCsProjection/DrawingIslandCsProjection.csproj @@ -0,0 +1,35 @@ + + + + + net8.0-windows10.0.22621.0 + enable + enable + x64;x86;ARM64 + + + win-x86;win-x64;win-arm64 + + + + + + + DrawingIslandComponents + + + $(OutDir) + 10.0.17763.0 + + + + + + + + + + + + + diff --git a/Samples/Islands/DrawingIsland/directory.build.props b/Samples/Islands/DrawingIsland/directory.build.props new file mode 100644 index 000000000..96ca6b023 --- /dev/null +++ b/Samples/Islands/DrawingIsland/directory.build.props @@ -0,0 +1,14 @@ + + + + + + True + + + $([MSBuild]::NormalizeDirectory('$(SolutionDir)', '_build', '$(Platform)', '$(Configuration)')) + $([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'bin')) + $([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'obj')) + + + diff --git a/Samples/SceneGraph/SampleGalleryApp/Samples/SceneNode/SceneNodePlayground.xaml.cs b/Samples/SceneGraph/SampleGalleryApp/Samples/SceneNode/SceneNodePlayground.xaml.cs index 94940e5a9..a283fbad9 100644 --- a/Samples/SceneGraph/SampleGalleryApp/Samples/SceneNode/SceneNodePlayground.xaml.cs +++ b/Samples/SceneGraph/SampleGalleryApp/Samples/SceneNode/SceneNodePlayground.xaml.cs @@ -82,6 +82,16 @@ private void SceneNodePlayground_Loaded(object sender, RoutedEventArgs e) meshRendererComponent.Material = material; sceneNode.Components.Add(meshRendererComponent); + + var animation = compositor.CreateScalarKeyFrameAnimation(); + var linearEasing = compositor.CreateLinearEasingFunction(); + animation.InsertKeyFrame(0f, 0f, linearEasing); + animation.InsertKeyFrame(1f, 360f, linearEasing); + animation.Duration = TimeSpan.FromSeconds(10); + animation.IterationBehavior = AnimationIterationBehavior.Forever; + + sceneNode.Transform.StartAnimation("RotationAngleInDegrees", animation); + sceneNode.Transform.RotationAxis = new Vector3(0, 1, 0); } private void SceneNodePlayground_Unloaded(object sender, RoutedEventArgs e) diff --git a/Samples/nuget.config b/Samples/nuget.config index 0b6213174..7b954d29d 100644 --- a/Samples/nuget.config +++ b/Samples/nuget.config @@ -10,9 +10,10 @@ - + +