Skip to content
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

Created RoundImageEx, Moved ImageEx Core Logic to Base Class #1100

Merged
merged 15 commits into from
May 22, 2017

Conversation

WilliamABradley
Copy link
Contributor

@WilliamABradley WilliamABradley commented Apr 15, 2017

I was looking for a way to clip an ImageEx Control, then I stumbled on to #277 where @JohnnyWestlake suggested restructuring the ImageEx to use ImageBrushes, but didn't want to because it would remove features.

He wanted to have the Original ImageEx Logic and I wanted the ability to make a Circular Image.
I thought, Why don't we have both?
Da, Da Da, Da Da, Da.
alt Meme

I shifted all of the Core Logic to the ImageExBase Base Class, ImageEx retains complete original functionality, and I created the new RoundImageEx to use Ellipses and ImageBrushes.

RoundImageEx loses GetAsCastingSource() & NineGrid, however, it gains the ability to add a Stroke w/ StrokeThickness & the ability to disable Stroke on Placeholder Images.

I also updated the ImageEx Sample Page, although it doesn't demonstrate using Stroke, or other RoundImageEx properties.

…ipped Image.

-Moved shared ImageEx Logic to ImageEx base.

-RoundImageEx has Properties to add Stroke, StrokeThickness and the ability to disable Stroke on Placeholder Images.

-Added RoundImageEx to ImageEx Sample Page.
-Removed Unused Usings.
@dnfclas
Copy link

dnfclas commented Apr 15, 2017

@WilliamABradley,
Thanks for your contribution.
To ensure that the project team has proper rights to use your work, please complete the Contribution License Agreement at https://cla2.dotnetfoundation.org.

It will cover your contributions to all .NET Foundation-managed open source projects.
Thanks,
.NET Foundation Pull Request Bot

@dnfclas
Copy link

dnfclas commented Apr 15, 2017

@WilliamABradley, thanks for signing the contribution license agreement. We will now validate the agreement and then the pull request.

Thanks, .NET Foundation Pull Request Bot

-Moved Stroke Visual State Strings to RoundImageEx.
-Attached PlaceholderSourceChanged (Woops) and removed SetSource as it was copied from ImageEx.Source.
-ShowStroke Visual State doesn't seem to work, testing the Stroke animation with EnableDependentAnimation works on the CommonStates, but not in StrokeStates, so I am temporarily setting StrokeThickness binding (ShowPlaceholderStroke does nothting).
@WilliamABradley
Copy link
Contributor Author

It all works except for the View State to show StrokeThickness on the Placeholder Image. Currently I have just set the StrokeThickness to the Placeholder Image, so the ShowPlaceholderStroke bool does nothing.

…t properties now work.

-Modified coding formatting to adhere to Style requests.

-Fixed missing Bracket.
@nmetulev nmetulev requested a review from hermitdave April 17, 2017 17:37
@nmetulev nmetulev added this to the v1.5 milestone Apr 17, 2017
@WilliamABradley WilliamABradley mentioned this pull request Apr 19, 2017
10 tasks
@hermitdave
Copy link
Contributor

@WilliamABradley I think something has wrong very wrong. Another PR is being referenced. That way you need to do is that the 2nd PR must start on dev again

@WilliamABradley
Copy link
Contributor Author

WilliamABradley commented Apr 21, 2017

@hermitdave How do you mean? This one was on the dev branch, but I wanted to create a second PR, but it wouldn't let me take a branch off of Microsoft/Dev, so I branched off of Origin/Dev and reverted the changes. How do I fix this mess?

Do you mean #1109? as This PR doesn't have any references to this PR, but that PR has references to this PR. Help :( I'm a GitHub noob. If I branch off of dev again it will have all of this code? (Fixed)

@hermitdave
Copy link
Contributor

maybe I didn't pay enough attention..

it however looks to me that there are conflicts for
Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageEx.Source.cs
Microsoft.Toolkit.Uwp.UI.Controls/ImageEx/ImageEx.cs

@WilliamABradley
Copy link
Contributor Author

@hermitdave I shifted the Core Logic out of ImageEx into a base class so that a RoundImageEx class can use the shared Logic. (The ImageBrush and Image implementations are different, so an XAML restyle wouldn't work here). ImageEx gets to retain all of it's functionality, and RoundImageEx gets to use ImageCache and most of the features of ImageEx, except it loses Nine Grid and GetAsCasting source, but you can use it to create circular images, which ImageEx can't do.

@WilliamABradley
Copy link
Contributor Author

@hermitdave I Merged back onto Microsoft/Dev if that helps?
Perhaps a better name for this control is ImageBrushEx?

@hermitdave
Copy link
Contributor

@WilliamABradley you need to run Please run '.\build.ps1 UpdateHeaders' from powershell to fix issue with file headers. I have reviewed much of the code yesterday. Will go through again over the weekend

@WilliamABradley
Copy link
Contributor Author

WilliamABradley commented Apr 22, 2017

psError.png

@hermitdave I'm getting this issue. Is it compatible with VS 2017? Or do I need something else? Do I need to specify a path parameter?


if (e.OldValue == null || e.NewValue == null || !e.OldValue.Equals(e.NewValue))
{
if (control is RoundImageEx round)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I know, C# 7 is not currently available for Continuous Integration. Please change to use C# 6 features such as as.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:( I looked it up and I couldn't find anything about it? It is located in quite a bit of my code, in this and in #1116, so it would be a pain to replace.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WilliamABradley If you want us to merge your branch, I recommend you to retarget your code to C# 6 only. To clarify, I am not against C# 7 but the fact is that the solution will not compile because CI does not support C# 7 for the moment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think you might be better off with something like this

RoundImageEx round = control as RoundImageEx
if (round != null)
{
}
else
{
}

Copy link
Contributor Author

@WilliamABradley WilliamABradley Apr 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Odonno Fixed it, I'll do the same for my other PR.

@WilliamABradley
Copy link
Contributor Author

@Odonno @hermitdave I have replaced the C# 7 features with C# 6 compatible features. I have also fixed an issue that caused a crash in .Net Native. I believe that this PR is ready for final review, as it is also now passing in AppVeyor :)

@WilliamABradley
Copy link
Contributor Author

@Odonno What happens now?

@hermitdave
Copy link
Contributor

A PR requires 2 reviews, I'll do mine maybe tonight. If all is well, i will merge it in

@WilliamABradley
Copy link
Contributor Author

WilliamABradley commented Apr 29, 2017

@hermitdave Awesome! When I get around to it, I also have a few more things I could contribute, such as:

  • A Helper for ContentDialogs to ensure only one is open at any time, a way to interrupt a dialog with another, if it is more important, and a way to interrupt a dialog and afterwards return to the previous dialog.
  • Another Helper for Producing a Cortana VCD.xml via Code (Currently CortanaExtensions on GitHub), based on the idea of NotificationExtensions, it allows you to easily populate the VCD at runtime, as well as populate it with translated strings.
  • A Control similar to AdaptiveGridView, except that it maintains aspect ratio, and uses ViewBoxes to scale the Items.

@hermitdave
Copy link
Contributor

@WilliamABradley create issues and uservoice entries for those.

As far as adaptive grid like control, maybe providing that as an option within AdaptiveGridView might be desirable.

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using Windows.Media.Casting;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings should be outside of the namespace

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using System;
using Windows.UI.Xaml;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings outside of namespace

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using Windows.UI.Xaml;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings outside namespace


if (e.OldValue == null || e.NewValue == null || !e.OldValue.Equals(e.NewValue))
{
RoundImageEx round = control as RoundImageEx;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion: There should be a virtual OnPlaceholderSourceChanged method that RoundImageEx can override and all this code should go in there, rather than be in the base class.

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using System;
using System.Collections.Generic;
using System.Threading;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings outside namespace

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using System;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings outside namespace

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using System;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings outside namespace

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings outside namespace

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usings outside namespace

@@ -0,0 +1,125 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure xaml styler has been run on this.

-Made OnPlaceholdersource changed, marked virtual to be overridden.

-ShowPlaceholderStroke still disabled as ViewState doesn't work.
@WilliamABradley
Copy link
Contributor Author

@ScottIsAFool Those changes have been made, however, ShowPlaceholderStroke currently does nothing, because I couldn't get it to work. The StrokeThickness on PlaceholderEllipse should default to 0, With the Visual State ShowStroke setting it to the desired Stroke value. Any ideas as to why it doesn't work?

@ScottIsAFool
Copy link
Contributor

@WilliamABradley you can't have a binding in the To value when used inside a control template. This would have to be set in code, sadly.

@WilliamABradley
Copy link
Contributor Author

@ScottIsAFool How would that be done? Would you attach an x:Name to the Animation so you update the value when the StrokeThickness changes, or some other way?

@ScottIsAFool
Copy link
Contributor

@WilliamABradley to be honest, looking at it, I'm not sure any of that is needed. Your ellipse's StrokeThickness is already being set and that should suffice. I don't think the ShowPlaceholderStroke property is even needed. I'm going to add a couple more comments to my review.

HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Opacity="1.0"
Stroke="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Stroke}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be a TemplateBinding

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VerticalAlignment="{TemplateBinding VerticalAlignment}"
Opacity="1.0"
Stroke="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Stroke}"
StrokeThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=StrokeThickness}">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also just be a TemplateBinding

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is applicable. From what that SO says, this is because the OP needed to basically convert to another value. As long as Stroke and StrokeThickness on RoundImageEx are using the same property types as Ellipse, then no conversion should be needed and TemplateBinding can be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops, It was only for the ImageBrushes anyway, not the Properties on the Ellipse.

</VisualState>
<VisualState x:Name="Unloaded" />
</VisualStateGroup>
<VisualStateGroup x:Name="StrokeStates">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this VisualState is even needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

DependencyProperty.Register(nameof(StrokeProperty), typeof(Brush), typeof(RoundImageEx), new PropertyMetadata(default(Brush)));

// Using a DependencyProperty as the backing store for ShowPlaceholderStroke. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ShowPlaceholderStrokeProperty =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this property even needed? If the dev doesn't want the placeholder to have a stroke, then the StrokeThickness should just be set to 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

{
// Using a DependencyProperty as the backing store for StrokeThickness. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyProperty.Register(nameof(StrokeThickness), typeof(double), typeof(RoundImageEx), new PropertyMetadata(default(double)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property should really be using Thickness, not double as its type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The StrokeThickness on an Ellipse is a double Property, this is just a pass-through. It wouldn't make sense for a circle to have differing thickness on different sides. It has no sides,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, ignore this. Apparently for Ellipse StrokeThickness uses double, not Thickness, like everywhere else does 8-)

-Fixed StrokeProperty.

-Replaced Bindings with TemplateBindings for Stroke and Thickness for Ellipses.
Copy link
Contributor

@nmetulev nmetulev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great.

Only request I have is about documentation. The sample page should be more clear that these are two different controls. At minimum, the code should have code for both controls.

Also, could you update the documentation for ImageEx to include this control?

<Setter.Value>
<ControlTemplate TargetType="controls:RoundImageEx">
<Grid>
<Ellipse x:Name="PlaceholderEllipse"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know its a bit late in the day. Any reason we are using Ellipse instead of Border ? Border would allow you to have image with rounded corner rather than elliptical images which is what default will be unless the user were to go override the XAML.

Personally Image with CornerRadius better than PeoplePicture (the one coming out in FCU)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that could work too, because you could set the corner radius to say 999, in order to create a round image anyway right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not difficult to create rounded image by tweaking corner radius. I am not sure if there's a default value that forces circular ellipse but my point is Border with RoundedCorner can be turned into fully circular image if desired.
Ellipse can't do that. Any thoughts on why we should go for one or the other ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Control name wouldn't make sense anymore. I could name it ImageBrushEx, although it would still be encapsulated so it wouldn't really be an ImageBrush you could attach to things,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point about naming. @nmetulev @ScottIsAFool @Odonno any thoughts on this ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing is, without setting the corner radius, it behaves practically the same as ImageEx, but without NineGrid and GetAsCastingSource

…rnerRadius as a larger number, e.g. 999.

-Setting Stroke is replaced with Setting BorderBrush and BorderThickness.

-Added RoundImageEx to ImageEx.md, as well as to the .bind file.
@WilliamABradley
Copy link
Contributor Author

@nmetulev I have updated the documentation.

@nmetulev
Copy link
Contributor

Thanks :)

@nmetulev nmetulev merged commit efe7217 into CommunityToolkit:dev May 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants