-
Notifications
You must be signed in to change notification settings - Fork 1
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
Create borders on demand #1
Conversation
border = new Border { BorderBrush = s_defaultBorderBrush, Tag = 123 }; | ||
view.Children.Insert(0, border); | ||
|
||
border.SetBinding(FrameworkElement.WidthProperty, new Binding |
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 sure what would be more of a hack, but the ViewManager class has the SetDimensions
method that you can override to intercept the width/height settings of the view. #Closed
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.
Fixed #Closed
return GetBorder(view) != null; | ||
} | ||
|
||
private Border GetBorder(TCanvas view) |
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.
GetBorder [](start = 23, length = 9)
I can see this being problematic if the actual first child is a border for some custom native component. #Closed
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.
One approach might be to subclass Canvas and maintain the state about whether the first child is a built-in Border there.
In reply to: 127780765 [](ancestors = 127780765)
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.
Fixed #Closed
view.Background = new SolidColorBrush(ColorHelpers.Parse(color)); | ||
if (!HasBorder(view) && ColorHelpers.IsTransparent(color)) | ||
return; | ||
|
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 think at some point we relied on transparent borders because without them the views weren't picked up as click targets. However, we've since done a bunch of work with the TouchHandler, so it may no longer be a problem, can you confirm if you have buttons with transparent backgrounds that they can still be targeted with and w/o a border #Closed
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.
Need to check that... #Closed
Would be good to clean up styles to follow the rest of the code base, I haven't got around to enabling any kind of linter, but just off the top of my head I saw some protected / private methods that needed to be ordered in the class and use { } on all blocks (even one liners) #Closed |
You probably need to remove this hack as well - https://github.com/Microsoft/react-native-windows/blob/67cf0d5db79a6665e4243f4e321c274ca1bbba0e/ReactWindows/ReactNative.Shared/UIManager/NativeViewHierarchyOptimizer.cs#L400-L415 In reply to: 315844695 [](ancestors = 315844695) |
view.BorderBrush = color.HasValue | ||
? new SolidColorBrush(ColorHelpers.Parse(color.Value)) | ||
: s_defaultBorderBrush; | ||
if (HasBorder(view) || color.HasValue && !ColorHelpers.IsTransparent(color.Value)) |
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.
This optimization needs to be done more carefully. If we first set border color to 0 (a fully transparent black color), this if
will ignore the request because the border wouldn't be visible. However if later we set border width to 2, the border will be created with the default border brush, which is an opaque black color, while it should be transparent. #Closed
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.
Fair enough, why not just eliminate the optimization?
In reply to: 127868591 [](ancestors = 127868591)
{ | ||
border.Width = dimensions.Width; | ||
border.Height = dimensions.Height; | ||
} |
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.
Just curious, do you think this is a better approach? XAML binding also worked, I wasn't sure what felt like more of a hack. Do you think there's any performance benefits to either? #Closed
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.
SetDimensions
looks simpler. IMO, difference in performance would be hard to measure. #Closed
|
||
return (TFrameworkElement)parent.Child; | ||
var pointerEvents = EnumHelpers.ParseNullable<PointerEvents>(pointerEventsValue) ?? PointerEvents.Auto; | ||
view.SetPointerEvents(pointerEvents); | ||
} |
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'm not sure why these props are here and not on either:
a) ReactViewManager
b) BaseViewManager
I'll have to do some digging. #Closed
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.
Ah, yeah these two props, accessible
and pointerEvents
should be on ReactViewManager (they currently are in the master branch of react-native-windows).
In reply to: 127970487 [](ancestors = 127970487)
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.
collapsible should also be moved, I added a PR - microsoft#1208
In reply to: 127974737 [](ancestors = 127974737,127970487)
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've also moved collapsable
to ReactViewManager #Closed
|
||
if (borderParent != null) | ||
{ | ||
x -= borderParent.GetLeftBorderWidth(); |
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.
GetLeftBorderWidth [](start = 34, length = 18)
Can you also delete these helpers, which are now no longer needed? I.e., delete ReactShadowNodeExtensions.cs. #Closed
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.
Fixed #Closed
{ | ||
/// <summary> | ||
/// Checks if the Canvas has a Border already. | ||
/// </summary> | ||
protected override bool HasBorder(TCanvas view) |
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.
HasBorder [](start = 32, length = 9)
Maybe we should just leave HasBorder and GetOrCreateBorder abstract, then you can implement them on ReactViewManager. If we're going to keep this base class, I'd rather not tie it to a specific Canvas subclass. #Closed
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.
Fixed #Closed
@@ -12,16 +13,37 @@ namespace ReactNative.UIManager | |||
/// View parent manager for bordered canvases. | |||
/// </summary> | |||
public abstract class BorderedCanvasManager<TCanvas> : BorderedViewParentManager<TCanvas> | |||
where TCanvas : Canvas | |||
where TCanvas : BorderedCanvas |
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.
BorderedCanvas [](start = 24, length = 14)
This can be reverted to Canvas. #Closed
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.
Fixed. I had to move SetDimensions to ReactViewManager as it changes the border size.
/// Adds a Border to a Canvas if it hasn't been added yet. | ||
/// </summary> | ||
protected abstract Border GetOrCreateBorder(TFrameworkElement view); | ||
|
||
|
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.
Extra newline. #Closed
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.
Fixed #Closed
@@ -1,4 +1,5 @@ | |||
using ReactNative.UIManager.Annotations; | |||
using ReactNative.Reflection; | |||
using ReactNative.UIManager.Annotations; |
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.
Delete this? #Closed
{ | ||
return (color & ~Transparent) == 0; | ||
} | ||
|
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.
Is this still being used or can it be deleted? #Closed
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.
Yup, it can be deleted too. #Closed
for (var i = GetChildCount(parent) - 1; i >= 0; i--) | ||
{ | ||
RemoveChildAt(parent, i); | ||
} |
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.
Can you inject a HasBorder check and just clear children in case there is no border? That way there's no net performance impact on views without a border. #Closed
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.
Fixed #Closed
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.
It turns out we use RemoveAllChildren quite frequently to tear down views via a depth-first recursive call to this method for the entire subtree being removed. Most views will not have a border, so it is a reasonable optimization.
In reply to: 128656455 [](ancestors = 128656455)
Can you use
For that matter, you could put it in the Refers to: ReactWindows/ReactNative.Shared/UIManager/BorderedCanvasManager.cs:16 in e5f9f64. [](commit_id = e5f9f64, deletion_comment = False) |
Is there something blocking you from putting this in the BorderedViewParentManager base class? Honestly the number of base classes here is quite useless at this point. I'm not even sure why all these base classes were introduced 😕 In reply to: 316868201 [](ancestors = 316868201) Refers to: ReactWindows/ReactNative.Shared/UIManager/BorderedCanvasManager.cs:16 in e5f9f64. [](commit_id = e5f9f64, deletion_comment = False) |
@antonkh - It turns out SetDimensions won't work after all, because the LayoutAnimation bypasses the SetDimensions API. We'll need to use the XAML binding approach. |
Closed, thanks for your iterations on this @antonkh |
* Integrate 5/14 * Change files * Fix CI #1 * Re-add BoundedConsumableBuffer.h * Integrate 5/18
Creating this pull request to start a dialog.