Commit Graph

23 Commits

Author SHA1 Message Date
Denis Koroskin
b52928c484 Include non-virtual nodes when collecting NodeRegions
Summary: Before this patch, we only collected virtual nodes in NodeRegions, because NodeRegions are only needed to implement ReactCompoundView.reactTargetForTouch() which is only interested in virtual nodes. In the next patch, FlatViewGroup will implement ReactCompoundViewGroup interface which requires knowledge of both virtual and non-virtual children. As a step towards that, we need to include non-virtual nodes in NodeRegions. This patch is implementing that. By itself, it should have not cause any changes in application behavior: we add non-virtual nodes to NodeRegions and mark them as non-virtual, then skip all non-virtual nodes in reactTagForTouch().

Reviewed By: ahmedre

Differential Revision: D3018047
2016-12-19 13:40:24 -08:00
Denis Koroskin
848bae2e95 Fix FlatUIImplementation.manageChildren() failing when moveFrom is not sorted
Summary:
Code in FlatUIImplementation.manageChildren() incorrectly assumed that moveFrom is sorted and moveTo is not, which is actually reverse: moveFrom is not sorted, and moveTo is. This means that we need to sort moveFrom before we can traverse it, and that we no longer need to sort moveTo (we did it by moving nodes to mNodesToMove first and then sorting it).

The sorting algorithm used is borrowed from Android implementation of insertion sort used in DualPivotQuicksort.doSort() when number of elements < INSERTION_SORT_THRESHOLD(32) which is 99.999% the case in UIImplementation.manageChildren() (most of the time this array is either empty or only contains 1 element).

Another (very rare) bug this is fixing is that the code only worked for FlatShadowNodes, but not all shadow nodes are FlatShadowNodes (there are rare exceptions, such as ARTShape, ARTGroup etc). New code works with all types of shadow nodes.

Reviewed By: ahmedre

Differential Revision: D2975787
2016-12-19 13:40:23 -08:00
Denis Koroskin
42fb9a3d91 Only collect state from nodes that have been updated
Summary: We are currently traversing entire tree every time there is any update to any of the nodes, which is hugely inefficient. Instead, we can early out for nodes that are known to contain no updates. This saves a lof of CPU. This optimization can be turned off, and an Exception will be thrown if there was an unexpected update.

Reviewed By: ahmedre

Differential Revision: D2975706
2016-12-19 13:40:23 -08:00
Denis Koroskin
b9e3ef2d5f Add @Nullable annotation to FlatShadowNode.obtainLayoutEvent()
Summary: Lint tool raised a warning. This diff is fixing it.

Reviewed By: sriramramani

Differential Revision: D2977649
2016-12-19 13:40:23 -08:00
Denis Koroskin
ca7a3519cf Store \"dirty\" and \"dirty descendant\" flags in every node instead of only marking root node as invalid
Summary: Right now invalidate always tell the root node that the tree is dirty, and next update will traverse the entire tree in search of changes. While this works correctly, it's not the most efficient implementation. It is more efficient to store dirty flag in every node, and skip entire subtrees if this node and all descendants are already up to date. This diff is a first step towards that optimization.

Reviewed By: ahmedre

Differential Revision: D2955197
2016-12-19 13:40:22 -08:00
Denis Koroskin
5305f3b68e Fix OnLayoutEvent dispatching wrong x/y coordinates
Summary:
OnLayoutEvent was incorrectly dispatching x/y coordinates relative to native View instead of relative to parent. This was causing issues in many cases, such as when Node was mounting to a View, in which case x/y would always be 0. This diff is fixing it.

This diff also caches last OnLayoutEvent to avoid dispatching the event on every layout even when layout didn't chance.

Reviewed By: ahmedre

Differential Revision: D2955087
2016-12-19 13:40:22 -08:00
Denis Koroskin
d1ccb6d23d Finalize many of FlatShadowNode methods
Summary: These methods (mostly getters/setters) are not meant to be overriden, so let's make them final. Hopefully, they will inline better, too.

Reviewed By: ahmedre

Differential Revision: D2933869
2016-12-19 13:40:21 -08:00
Ahmed El-Helw
99d95d8168 Fix TextInput in React Nodes
Summary:
@public Relax the constraint on ReactTextInputManager.
The TextInput Advanced screen looked different with and without
nodes, namely child Text items were not being rendered on the Nodes version.
This patch fixes that.

Differential Revision: D2930800
2016-12-19 13:40:21 -08:00
Denis Koroskin
74c72111f1 Rename mIsOverflowVisible to a more descriptive mClipToBounds
Summary: A simple refactoring diff that should make code a little easier to read. No functional changes.

Reviewed By: ahmedre

Differential Revision: D2867718
2016-12-19 13:40:20 -08:00
Martin Konicek
0b79d44dcf Less Catalyst, more React
Summary:
Catalyst is the old project name. Rename a few files.

@public

Reviewed By: bestander

Differential Revision: D2859553
2016-12-19 13:40:20 -08:00
Denis Koroskin
2fb7ebfb7b Reset NodeRegion when a node gets mounted to a View
Summary: Small optimization. Once we mount a Node to a View, its NodeRegion is not used anymore with RCTText being an exception, but it will correct itself automatically upon updateNodeRegion call. This patch allows the dead object to get garbage collected.

Reviewed By: ahmedre

Differential Revision: D2816331
2016-12-19 13:40:19 -08:00
Alexander Blom
2daf696064 Move UIManager annotations to separate package
Summary:
Moves ReactProp and ReactPropGroup to `com.facebook.react.uimanager.annotations`. This is needed
so that future annotation processor can run on code inside the com.facebook.react.uimanager package.

@public

Reviewed By: astreet

Differential Revision: D2754842
2016-12-19 13:40:19 -08:00
Denis Koroskin
b10474c333 Disallow mounting virtual nodes to Views
Summary: Virtual shadow nodes, such as RCTRawText, RCTTextInlineImage etc cannot be mounted to a View (ViewManager will throw an Exception if we ever try to). This diff is adding a check to make sure that Exception is never thrown.

Reviewed By: ahmedre

Differential Revision: D2800869
2016-12-19 13:40:19 -08:00
Denis Koroskin
b321ea98d3 Properly clip child Views in FlatViewGroup
Summary:
Everything (but Views) are drawn using AbstractDrawCommand (or its derivative, like DrawBorder or DrawBackgroundColor) and supports clipping properly. Views however are drawn using an assumption that Android will clip them manually. This is however not always true. One example is if an element A mounts to a View, and its parent B doesn't but has overflow: hidden and thus should clip the child.

There are 2 ways to fix this:
- pop every element that has overflow: hidden to its own View. In this case, its children will always be correctly clipped. This is however very inefficient, especially if overflow: hidden is default (which it is!) which means that almost every React element must be backed by an Android View.
- add clipping information to DrawView, similar to how AbstractDrawCommand has it.

This diff implements the latter approach.

Reviewed By: ahmedre

Differential Revision: D2792375
2016-12-19 13:40:18 -08:00
Denis Koroskin
6f06f76e38 Implement overflow:visible/hidden attribute (defaults to visible)
Summary:
Prior to this patch DrawCommands weren't get clipped by parent DrawCommands at all. For example, a <View> element with size 200x200 with overflow:hidden should clip its child which is 400x400, but this didn't happen. However, if parent <View> would mount to an Android View, it would clip the child regardless of the overflow attribute value (because Android Views always clip whatever is drawing inside that View against its boundaries).

This diff is fixing these issue, implementing overflow attribute support and making clipping behavior consistent between nodes that mount to View and nodes that don't.

Reviewed By: ahmedre

Differential Revision: D2768643
2016-12-19 13:40:17 -08:00
Denis Koroskin
99d1c15c4d Properly implement manageChildren(), correctly handling moveFrom and moveTo
Summary: Previously, manageChildren() would throw an Exception if moveFrom != null or moveTo != null. This is obviously not correct, because no matter how rare these events are, they actually happen in practice. This diff re-implements manageChildren() to support all the cases. It does so by first removing all the elements that need to be removed. During removal, those elements that need to be moved will be temporarily put into `mNodesToMove` array. Then the next step is to add all elements (including new elements to add, and existing elements to move). There is an fast path when only one of another is present. If both types are present, they need to be sorted, first, to maintain correct orded. A similar optimization is applied to `removeChildren()`: there is a fast path when moveFrom == null and a another fast path when removeFrom == null. When both are != null, a merge sort is used (it is assumed that both moveFrom and removeFrom are sorted).

Reviewed By: ahmedre

Differential Revision: D2768689
2016-12-19 13:40:17 -08:00
Denis Koroskin
381bf1b76f Implement TextNodeRegion
Summary: NodeRegion is only able to describe a rectangular region for touch, which is not good enough for text, where we want to be able to assign different touch ids to individual words (and those can span more than one line and in general have non-rectangular structure). This diff adds TextNodeRegion which inserts additional markers into text Layout to allow individual words to have unique react tags.

Reviewed By: ahmedre

Differential Revision: D2757387
2016-12-19 13:40:17 -08:00
Denis Koroskin
1da7049426 ForceMountToView when Opacity or other View-specific properties are applied to a FlatShadowNode
Summary: @public There are some properties, such as alpha or scale that we ONLY handle on a View level. This means that whenever we encounter a FlatShadowNode with this property, it should be mapped to a View. This diff is doing exactly this.

Reviewed By: ahmedre

Differential Revision: D2694495
2016-12-19 13:40:16 -08:00
Denis Koroskin
dad378e394 Add NodeRegion to allow any FlatShadowNode to respond to touch events
Summary: @public When Android dispatches `MotionEvent` to `ReactRootView`, it needs to find a correspoding react node that should receive it. To be able to do it, we need to store boundaries of every `FlatShadowNode` in `FlatViewGroup`. Then we can iterate over node boundaries and find one that contains the touch event coordinates.

Reviewed By: sriramramani

Differential Revision: D2694197
2016-12-19 13:40:16 -08:00
Denis Koroskin
8de2acd3a9 Allow FlatShadowNode mouting to its own view
Summary: @public This diff adds a `FlatShadowNode.forceMountToView()` method that will render its contents in it own `View`.

Reviewed By: sriramramani

Differential Revision: D2564502
2016-12-19 13:40:16 -08:00
Denis Koroskin
f19acaed4b Implement background in FlatShadowNode
Summary: @public Similar to a `DrawBorder` patch, this diff adds `DrawBackground` and implements `ViewProps.BACKGROUND_COLOR` property in `FlatShadowNode` with it.

Reviewed By: sriramramani

Differential Revision: D2564466
2016-12-19 13:40:15 -08:00
Denis Koroskin
760422525e Add support for RCTImageView in FlatShadowHierarchyManager
Summary: @public This patch adds basic support for RCTImageView (only 'src', 'tintColor' and 'resizeMode' properties are supported for now), and a concept of AttachDetachListener that is required to support it to FlatUIImplementations.

Reviewed By: sriramramani

Differential Revision: D2564389
2016-12-19 13:40:15 -08:00
Denis Koroskin
5c2f536e9a Add support for RCTText under FlatUIImplementation
Summary: @public Initial version of FlatUIImplementation lacks any primitives support (such as RCTText, RCTImageView or RCTView). This diff add the first part, RCTText (alongside with RCTVirtualText and RCTRawText).

Reviewed By: sriramramani

Differential Revision: D2693348
2016-12-19 13:40:15 -08:00