in source/uwp/Renderer/lib/TileControl.cpp [78:230]
void TileControl::RefreshContainerTile()
{
winrt::BackgroundImageFillMode fillMode = m_adaptiveBackgroundImage.FillMode();
winrt::HAlignment hAlignment = m_adaptiveBackgroundImage.HorizontalAlignment();
winrt::VAlignment vAlignment = m_adaptiveBackgroundImage.VerticalAlignment();
int numberSpriteToInstanciate{1};
int numberImagePerColumn{1};
int numberImagePerRow{1};
float offsetVerticalAlignment{};
float offsetHorizontalAlignment{};
// If we don't have dimensions yet, just make the image the size of
// the container until we get the right dimensions.
if (m_imageSize.Width && m_imageSize.Height)
{
switch (fillMode)
{
case winrt::BackgroundImageFillMode::RepeatHorizontally:
numberImagePerRow = static_cast<int>(ceil(m_containerSize.Width / m_imageSize.Width));
numberImagePerColumn = 1;
switch (vAlignment)
{
case winrt::VAlignment::Bottom:
offsetVerticalAlignment = m_containerSize.Height - m_imageSize.Height;
break;
case winrt::VAlignment::Center:
offsetVerticalAlignment = static_cast<float>((m_containerSize.Height - m_imageSize.Height) / 2.0f);
break;
case winrt::VAlignment::Top:
default:
break;
}
break;
case winrt::BackgroundImageFillMode::RepeatVertically:
numberImagePerRow = 1;
numberImagePerColumn = static_cast<int>(ceil(m_containerSize.Height / m_imageSize.Height));
switch (hAlignment)
{
case winrt::HAlignment::Right:
offsetHorizontalAlignment = m_containerSize.Width - m_imageSize.Width;
break;
case winrt::HAlignment::Center:
offsetHorizontalAlignment = static_cast<float>((m_containerSize.Width - m_imageSize.Width) / 2.0f);
break;
case winrt::HAlignment::Left:
default:
break;
}
break;
case winrt::BackgroundImageFillMode::Repeat:
numberImagePerColumn = static_cast<int>(ceil(m_containerSize.Height / m_imageSize.Height));
numberImagePerRow = static_cast<int>(ceil(m_containerSize.Width / m_imageSize.Width));
break;
case winrt::BackgroundImageFillMode::Cover:
default:
numberImagePerColumn = 1;
numberImagePerRow = 1;
offsetHorizontalAlignment = 0;
offsetVerticalAlignment = 0;
}
}
numberSpriteToInstanciate = numberImagePerColumn * numberImagePerRow;
int count = static_cast<int>(m_xamlChildren.size());
// Get containerElement.Children
winrt::IVector<winrt::UIElement> children{};
// Not sure what is the need to convert to xaml::controls::Panel?
if (const auto containerElementAsPanel = m_containerElement.try_as<winrt::Panel>())
{
children = containerElementAsPanel.Children();
}
if (numberSpriteToInstanciate > count)
{
// instanciate all elements not created yet
for (int x = 0; x < (numberSpriteToInstanciate - count); x++)
{
winrt::Rectangle rectangle;
children.Append(rectangle.as<winrt::UIElement>());
m_xamlChildren.push_back(rectangle);
}
}
else
{
// remove elements not used now
for (int x = 0; x < (count - numberSpriteToInstanciate); x++)
{
children.RemoveAtEnd();
m_xamlChildren.pop_back();
}
}
// Change positions+brush for all actives elements
for (int x = 0, index = 0; x < numberImagePerRow; x++)
{
for (int y = 0; y < numberImagePerColumn; y++, index++)
{
// Get Rectangle
auto rectangle = m_xamlChildren[index];
// For cover, the bitmapimage must be scaled to fill the container and then clipped to only the
// necessary section Set rectangle.
rectangle.Fill(m_brushXaml);
double originPositionX{0.0}, originPositionY{0.0};
if (fillMode != winrt::BackgroundImageFillMode::Cover)
{
originPositionX = (x * m_imageSize.Width) + offsetHorizontalAlignment;
originPositionY = (y * m_imageSize.Height) + offsetVerticalAlignment;
}
// Set Left and Top for rectangle
winrt::Canvas::SetLeft(rectangle, originPositionX);
winrt::Canvas::SetTop(rectangle, originPositionY);
double imageWidth{0.0}, imageHeight{0.0};
if (fillMode == winrt::BackgroundImageFillMode::Cover)
{
imageWidth = m_containerSize.Width;
imageHeight = m_containerSize.Height;
}
else
{
imageWidth = m_imageSize.Width;
imageHeight = m_imageSize.Height;
}
// Set Width and Height for Rectangle
rectangle.Width(imageWidth);
rectangle.Height(imageHeight);
if (fillMode == winrt::BackgroundImageFillMode::Cover)
{
m_brushXaml.Stretch(winrt::Stretch::UniformToFill);
// Vertical and Horizontal Alignments map to the same values in our shared model and UWP, so we just cast
m_brushXaml.AlignmentX(static_cast<winrt::AlignmentX>(hAlignment));
m_brushXaml.AlignmentY(static_cast<winrt::AlignmentY>(vAlignment));
}
}
}
}