-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a MosaicControl to repeat an image #702
Conversation
Hi @samoteph, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution! TTYL, DNFBOT; |
@samoteph, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
@@ -1,6 +1,7 @@ | |||
{ | |||
"dependencies": { | |||
"Microsoft.NETCore.UniversalWindowsPlatform": "5.1.0", | |||
"Robmikh.CompositionSurfaceFactory": "0.7.0-alpha", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you mind updating the nuspec in /build folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry but I don't understand what must i do.
Could you give me some hint ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I missed this question. Can you update this file: https://github.com/Microsoft/UWPCommunityToolkit/blob/dev/build/Microsoft.Toolkit.Uwp.UI.Controls.nuspec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done !
@@ -193,6 +198,7 @@ | |||
<ItemGroup> | |||
<EmbeddedResource Include="Properties\Microsoft.Windows.Toolkit.UI.Controls.rd.xml" /> | |||
</ItemGroup> | |||
<ItemGroup /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not required :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh:)
/// <summary> | ||
/// MosaicControl is created with XAML | ||
/// </summary> | ||
PureXaml, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why exposing this? I understand the need to use Xaml when composition is not available (and I love this fallback) but why as an user could I change it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point ! I'll change the exposition of the enum to private.
} | ||
|
||
// Using a DependencyProperty as the backing store for ScrollViewer. This enables animation, styling, binding, etc... | ||
public static readonly DependencyProperty ScrollViewerContainerProperty = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We try to keep all DP first in the file (sorry for being picky)
this.RefreshMove(this.OffsetX + this.animationX, this.OffsetY + this.animationY); | ||
} | ||
|
||
object lockerOffset = new object(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must define an access modifier
} | ||
} | ||
|
||
// retire les sprites visual en trop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments must be in english (But I agree with you, it is a shame :))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never again French words in this page !
/// When the control is in Design mode, Composition is not allowed. | ||
/// </summary> | ||
/// <returns>the UIStrategy choosed</returns> | ||
private UIStrategy GetUIStrategy() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not a getter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remove the DP UIStrategy and replace by a simple property with a getter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect. A cool .md in the doc folder and we are good to go
Impressive control!! Just some tiny comments and a documentation and we are good to go :) |
…e + Documentation
if (rootElement != null) | ||
{ | ||
this.rootElement = rootElement; | ||
rootElement.SizeChanged += RootElement_SizeChanged; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OnApplyTemplate()
can get called multiple times, so always safer to unhook before hooking any events in here,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the tips !
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"> | ||
<Style TargetType="controls:MosaicControl"> | ||
<Setter Property="Template"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the benefit of Xbox One controller navigation (and keyboard navigation), can we add <Setter Property="IsTabStop" Value="False" />
to this? Whilst it's content is fine to be focusable I don't think there's any reason the container should be by default.
{ | ||
// Using a DependencyProperty as the backing store for ScrollViewer. This enables animation, styling, binding, etc... | ||
public static readonly DependencyProperty ScrollViewerContainerProperty = | ||
DependencyProperty.Register("ScrollViewerContainer", typeof(FrameworkElement), typeof(MosaicControl), new PropertyMetadata(null, OnScrollViewerContainerChange)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline with the style of some of the other controls in the project, you may want to consider DependencyProperty.Register(nameof(ScrollViewerContainer)....
rather than DependencyProperty.Register("ScrollViewerContainer"...
(same applies for the rest of the DP's)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: Remove uses of this.
It would be good to have an image that looks good as it's tiled.
<Grid> | ||
<Border | ||
x:Name="RootElement" | ||
Background="{TemplateBinding Background}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Template bind the border properties as well
/// <summary> | ||
/// Gets or sets an X offset of the image | ||
/// </summary> | ||
public double OffsetX |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why add new offset properties instead of just using margin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OffsetX and OffsetY are not destined to manage the layout but the starting position of the repeated image. It's like properties AlignmentX and AlignmentY of the ImageBrush class in WPF.
public static readonly DependencyProperty AnimationDurationProperty = | ||
DependencyProperty.Register(nameof(AnimationDuration), typeof(double), typeof(MosaicControl), new PropertyMetadata(30.0, OnAnimationDuration)); | ||
|
||
private FrameworkElement rootElement = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name private member variables with _pascalCase
/// <summary> | ||
/// MosaicControl is created with XAML | ||
/// </summary> | ||
PureXaml, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why support xaml at all for something like this? Rendering and memory would be too much
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rendering with XAML has been created at first for the XAML Viewer (when it'll be functionnal ^^) and after for version that doesn't support Composition. As it use a unique ImageBrush it is not too expensive for the memory consumption and the performances are not bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to go for me..
@skendrot, @JohnnyWestlake ok for the merge? |
Not too excited about the new dependency on Robmikh.CompositionSurfaceFactory |
Robert is a developer on the Windows Composition team so I'm fine with this dependency. |
Maybe Robert would be OK to integrate his CompositionSurfaceFactory in the toolkit :) |
Ping @robmikh :) |
perhaps stupid question but can we use this instead? |
This is not a stupid question at all. In case of a Device Lost, the image must be reloaded. CompositionSurfaceFactory does all the work for us. SurfaceLoader doesn't (I guess). |
There's also a huge performance gain: CompositionSurfaceFactory loads images a lot faster than SurfaceLoader. |
Hi sorry, I missed this in the torrent of notifications! :) I have no qualms about adding CompositionSurfaceFactory, I'm just not sure how it would work. It's currently a C++/CX component, so I'm guessing it would become its own package in a sub-namespace? Just know that I don't remember if I've also recently added |
No worry :) |
Up :) |
I think @shenchauhan is working on removing surfaceloader |
it 's a go for me. just a second reviewer |
Do you mind removing conflicts? (pretty please :)) |
…as Robmikh has suggested
Done ? |
ok trying to summon another reviewer:) I'll merge else |
Oky :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of comments around styling and also possibly consider using parallax that we will be shipping in the toolkit.
/// </summary> | ||
public sealed class MosaicControl : ContentControl | ||
{ | ||
private FrameworkElement rootElement = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the .NET Core coding stlyes mentioned here: https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md
so it should be _rootElement
/// <param name="e">arguments</param> | ||
private async void RootElement_SizeChanged(object sender, SizeChangedEventArgs e) | ||
{ | ||
Debug.WriteLine("sizeChanged=" + e.NewSize.Width); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the Debug.WriteLine
{ | ||
var speedRatio = this.ParallaxSpeedRatio; | ||
|
||
scrollX = -((scrollviewer.HorizontalOffset * scrollviewer.ActualWidth) / scrollviewer.ViewportWidth) * speedRatio; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it better to use the parallax behavior that's going into the Toolkit? (I think there is a PR for it already) This way there is a consistent way for people to adjust the parallax effect across the toolkit. Appreciate that the PR hasn't gone through yet, but thought I would ask the question here in case you weren't aware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the Mosaic control integrate an infinite scrolling effect. this is made by using a Composition expression. this expression manage the offset modulo (included negative value) of the scrolling. This expression is used for manual move (OffsetX, OffsetY) + parallax effect and this is the core of the control. The parallax Service is a great helper to create quickly a parallax effect but in this case the scenario is too complicated I think for be used internally.
Do you mind removing conflicts? (pretty please :)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! 👍 Nice control.
Thanks guys ! |
As asked in the issue #658, I propose MosaicControl.
It works with XAML or Composition (Composition is the default).
You can animate the image or synchronize it with a ScrollViewer to create a parallax effect.