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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 101 additions & 41 deletions Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIsland.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace winrt::DrawingIslandComponents::implementation
const winrt::Compositor& compositor)
{
m_output.Compositor = compositor;
m_output.TextRenderer = std::make_shared<TextRenderer>(m_output.Compositor);

// Create the Compositor and the Content:
// - The Bridge's connection to the Window will keep everything alive, and perform an
Expand Down Expand Up @@ -75,7 +76,8 @@ namespace winrt::DrawingIslandComponents::implementation
m_background.Visual = nullptr;

m_items.Visuals = nullptr;
m_items.SelectedVisual = nullptr;
m_items.VisualItems.clear();
m_items.SelectedItem = nullptr;

// TODO: Enable Mica on Win 11
#if FALSE
Expand Down Expand Up @@ -234,11 +236,13 @@ namespace winrt::DrawingIslandComponents::implementation
winrt::Windows::Graphics::RectInt32 screenRect{ static_cast<int>(x + 0.5), static_cast<int>(y + 0.5), 0, 0 };
auto logicalRect = m_island.CoordinateConverter().ConvertScreenToLocal(screenRect);
float2 localPoint{ logicalRect.X, logicalRect.Y };
auto hitTestVisual = HitTestVisual(localPoint);
auto hitTestElement = HitTestItem(localPoint);

// Find the automation peer for the hit test visual if any.
if (nullptr != hitTestVisual)
if (nullptr != hitTestElement)
{
auto& hitTestVisual = hitTestElement->GetVisual();

auto iterator = std::find_if(
m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), [&hitTestVisual](auto const& automationPeer)
{
Expand All @@ -259,30 +263,38 @@ namespace winrt::DrawingIslandComponents::implementation
winrt::com_ptr<IRawElementProviderFragment>
DrawingIsland::GetFragmentInFocus() const
{
// Find the currently selected visual's automation peer.
auto iterator = std::find_if(
m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), [visual = m_items.SelectedVisual](auto const& automationPeer)
{
return automationPeer.Match(visual);
});

if (m_uia.AutomationPeers.end() != iterator)
if (m_items.SelectedItem != nullptr)
{
// Return the automation provider if we found an automation peer for the selected visual.
return iterator->GetAutomationProvider().as<IRawElementProviderFragment>();
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<IRawElementProviderFragment>();
}
}

return nullptr;
}


winrt::Visual
DrawingIsland::HitTestVisual(
VisualItem*
DrawingIsland::HitTestItem(
float2 const& point) const
{
winrt::Visual selectedVisual{ nullptr };
for (winrt::Visual visual : m_items.Visuals)
// Iterate from the end of the vector, i.e., from front to back.
for (size_t i = m_items.VisualItems.size(); i != 0; i--)
{
VisualItem* item = m_items.VisualItems[i - 1].get();
auto& visual = item->GetVisual();

winrt::float3 const offset = visual.Offset();
float2 const size = visual.Size();

Expand All @@ -291,11 +303,10 @@ namespace winrt::DrawingIslandComponents::implementation
point.y >= offset.y &&
point.y < offset.y + size.y)
{
selectedVisual = visual;
return item;
}
}

return selectedVisual;
return nullptr;
}


Expand Down Expand Up @@ -507,6 +518,7 @@ namespace winrt::DrawingIslandComponents::implementation
case winrt::Windows::System::VirtualKey::Escape:
{
m_items.Visuals.RemoveAll();
m_items.VisualItems.clear();

// Update accessibility.
m_uia.FragmentRoot->RemoveAllChildren();
Expand Down Expand Up @@ -581,7 +593,7 @@ namespace winrt::DrawingIslandComponents::implementation
void
DrawingIsland::Input_OnPointerReleased()
{
m_items.SelectedVisual = nullptr;
m_items.SelectedItem = nullptr;
}


Expand All @@ -608,22 +620,39 @@ namespace winrt::DrawingIslandComponents::implementation
const float2 point,
bool controlPressed)
{
m_items.SelectedVisual = HitTestVisual(point);
m_items.SelectedItem = HitTestItem(point);

if (m_items.SelectedVisual)
if (m_items.SelectedItem != nullptr)
{
winrt::float3 const offset = m_items.SelectedVisual.Offset();
VisualItem* 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;

m_items.Visuals.Remove(m_items.SelectedVisual);
m_items.Visuals.InsertAtTop(m_items.SelectedVisual);
// 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.VisualItems.empty() && m_items.VisualItems.back().get() != item)
{
auto i = std::find_if(
m_items.VisualItems.begin(),
m_items.VisualItems.end(),
[item](auto& elem) { return elem.get() == item; }
);
if (i != m_items.VisualItems.end())
{
std::rotate(i, i + 1, m_items.VisualItems.end());
}
}

// Update automation.
// First find the existing automation peer.
auto iterator = std::find_if(
m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), [visual = m_items.SelectedVisual](auto const& automationPeer)
m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(), [visual](auto const& automationPeer)
{
return automationPeer.Match(visual);
});
Expand Down Expand Up @@ -651,18 +680,21 @@ namespace winrt::DrawingIslandComponents::implementation
void
DrawingIsland::OnRightClick(const float2 point)
{
winrt::Visual selectedVisual = HitTestVisual(point);
// TODO - what is the purpose of this?
UNREFERENCED_PARAMETER(point);
// VisualElement* selectedVisual = HitTestVisual(point);
}

void
DrawingIsland::Input_OnPointerMoved(
const winrt::PointerEventArgs& args)
{
if (m_items.SelectedVisual)
if (m_items.SelectedItem)
{
auto& visual = m_items.SelectedItem->GetVisual();
float2 const point = args.CurrentPoint().Position();

m_items.SelectedVisual.Offset(
visual.Offset(
{ point.x + m_items.Offset.x,
point.y + m_items.Offset.y,
0.0f });
Expand All @@ -682,7 +714,16 @@ namespace winrt::DrawingIslandComponents::implementation
{
if (m_prevState.RasterizationScale != m_island.RasterizationScale())
{
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.VisualItems)
{
item->OnDpiScaleChanged();
}
}

if (m_prevState.LayoutDirection != m_island.LayoutDirection())
Expand Down Expand Up @@ -746,20 +787,39 @@ namespace winrt::DrawingIslandComponents::implementation
float2 const point,
bool halfTransparent)
{
winrt::SpriteVisual visual = m_output.Compositor.CreateSpriteVisual();
visual.Brush(halfTransparent ?
m_output.HalfTransparentColorBrushes[m_output.CurrentColorIndex] :
m_output.ColorBrushes[m_output.CurrentColorIndex]);
// 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<TextItem>(
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 });

float const BlockSize = 30.0f;
visual.Size({ BlockSize, BlockSize });
visual.Offset({ point.x - BlockSize / 2.0f, point.y - BlockSize / 2.0f, 0.0f });
// Add the new text element to the vector.
m_items.VisualItems.push_back(std::move(textItem));

// Add the visual as a child of the container visual.
m_items.Visuals.InsertAtTop(visual);

m_items.SelectedVisual = visual;
m_items.Offset.x = -BlockSize / 2.0f;
m_items.Offset.y = -BlockSize / 2.0f;
m_items.SelectedItem = m_items.VisualItems.back().get();
m_items.Offset.x = -size.x / 2.0f;
m_items.Offset.y = -size.y / 2.0f;

Accessibility_CreateItemFragment(visual);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "DrawingIsland.g.h"
#include "IslandFragmentRoot.h"
#include "TextRenderer.h"
#include "TextItem.h"

namespace winrt::DrawingIslandComponents::implementation
{
Expand Down Expand Up @@ -90,7 +92,7 @@ namespace winrt::DrawingIslandComponents::implementation
winrt::com_ptr<IRawElementProviderFragment> GetFragmentInFocus() const override;

private:
winrt::Visual HitTestVisual(
VisualItem* HitTestItem(
float2 const& point) const;

void Accessibility_Initialize();
Expand Down Expand Up @@ -194,6 +196,8 @@ namespace winrt::DrawingIslandComponents::implementation
{
winrt::Compositor Compositor{ nullptr };

std::shared_ptr<TextRenderer> TextRenderer;

// Current color used for new items
unsigned int CurrentColorIndex = 0;

Expand Down Expand Up @@ -244,7 +248,8 @@ namespace winrt::DrawingIslandComponents::implementation
struct
{
winrt::VisualCollection Visuals{ nullptr };
winrt::Visual SelectedVisual{ nullptr };
std::vector<std::unique_ptr<VisualItem>> VisualItems;
VisualItem* SelectedItem{ nullptr };
winrt::SpriteVisual CurrentColorVisual{ nullptr };
float2 Offset{};
} m_items;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@
<ClInclude Include="DrawingIsland.h">
<DependentUpon>Components.idl</DependentUpon>
</ClInclude>
<ClInclude Include="TextItem.h" />
<ClInclude Include="TextRenderer.h" />
<ClInclude Include="VisualItem.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="IslandFragmentRoot.cpp" />
Expand All @@ -142,6 +145,9 @@
<DependentUpon>Components.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="TextItem.cpp" />
<ClCompile Include="TextRenderer.cpp" />
<ClCompile Include="VisualItem.cpp" />
</ItemGroup>
<ItemGroup>
<Midl Include="Components.idl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
<ClCompile Include="NodeSimpleFragment.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TextItem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TextRenderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="VisualItem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
Expand All @@ -33,6 +42,15 @@
<ClInclude Include="IslandFragmentRoot.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TextItem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TextRenderer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="VisualItem.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Midl Include="Components.idl" />
Expand Down
35 changes: 35 additions & 0 deletions Samples/Islands/DrawingIsland/DrawingIslandComponents/TextItem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include "pch.h"
#include "TextItem.h"
#include "IslandFragmentRoot.h"

namespace winrt::DrawingIslandComponents::implementation
{
TextItem::TextItem(
std::shared_ptr<TextRenderer> const& textRenderer,
Windows::UI::Color backgroundColor,
Windows::UI::Color textColor,
std::wstring const& text
) :
VisualItem(textRenderer->GetCompositor()),
m_textRenderer(textRenderer),
m_backgroundColor(backgroundColor),
m_textColor(textColor),
m_text(text)
{
InitializeVisual();
}

void TextItem::InitializeVisual()
{
// Render the text to determine the size.
m_textRenderer->Render(m_text.c_str(), m_backgroundColor, m_textColor, GetVisual());
}

void TextItem::OnDpiScaleChanged()
{
InitializeVisual();
}
}
Loading