Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
fb4a87ad
Commit
fb4a87ad
authored
Sep 22, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ParentDataWidget and InheritedWidget to fn3
parent
5fb2cb32
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
266 additions
and
19 deletions
+266
-19
basic.dart
packages/flutter/lib/src/fn3/basic.dart
+118
-7
framework.dart
packages/flutter/lib/src/fn3/framework.dart
+144
-8
render_object_widget_test.dart
packages/unit/test/fn3/render_object_widget_test.dart
+1
-1
stateful_component_test.dart
packages/unit/test/fn3/stateful_component_test.dart
+2
-2
widget_tester.dart
packages/unit/test/fn3/widget_tester.dart
+1
-1
No files found.
packages/flutter/lib/src/fn3/basic.dart
View file @
fb4a87ad
...
...
@@ -467,11 +467,59 @@ class Stack extends MultiChildRenderObjectWidget {
void
updateRenderObject
(
RenderStack
renderObject
,
Stack
oldWidget
)
{
// Nothing to update
}
// TODO(abarth): Update parent data
}
// TODO(abarth): Positioned
class
Positioned
extends
ParentDataWidget
{
Positioned
({
Key
key
,
Widget
child
,
this
.
top
,
this
.
right
,
this
.
bottom
,
this
.
left
})
:
super
(
key:
key
,
child:
child
);
final
double
top
;
final
double
right
;
final
double
bottom
;
final
double
left
;
void
debugValidateAncestor
(
Widget
ancestor
)
{
assert
(()
{
'Positioned must placed inside a Stack'
;
return
ancestor
is
Stack
;
});
}
void
applyParentData
(
RenderObject
renderObject
)
{
assert
(
renderObject
.
parentData
is
StackParentData
);
final
StackParentData
parentData
=
renderObject
.
parentData
;
bool
needsLayout
=
false
;
if
(
parentData
.
top
!=
top
)
{
parentData
.
top
=
top
;
needsLayout
=
true
;
}
if
(
parentData
.
right
!=
right
)
{
parentData
.
right
=
right
;
needsLayout
=
true
;
}
if
(
parentData
.
bottom
!=
bottom
)
{
parentData
.
bottom
=
bottom
;
needsLayout
=
true
;
}
if
(
parentData
.
left
!=
left
)
{
parentData
.
left
=
left
;
needsLayout
=
true
;
}
if
(
needsLayout
)
renderObject
.
markNeedsLayout
();
}
}
class
Grid
extends
MultiChildRenderObjectWidget
{
Grid
(
List
<
Widget
>
children
,
{
Key
key
,
this
.
maxChildExtent
})
...
...
@@ -514,8 +562,6 @@ class Flex extends MultiChildRenderObjectWidget {
renderObject
.
alignItems
=
alignItems
;
renderObject
.
textBaseline
=
textBaseline
;
}
// TODO(abarth): Update parent data
}
class
Row
extends
Flex
{
...
...
@@ -536,7 +582,28 @@ class Column extends Flex {
})
:
super
(
children
,
key:
key
,
direction:
FlexDirection
.
vertical
,
justifyContent:
justifyContent
,
alignItems:
alignItems
,
textBaseline:
textBaseline
);
}
// TODO(abarth): Flexible
class
Flexible
extends
ParentDataWidget
{
Flexible
({
Key
key
,
this
.
flex
:
1
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
final
int
flex
;
void
debugValidateAncestor
(
Widget
ancestor
)
{
assert
(()
{
'Flexible must placed inside a Flex'
;
return
ancestor
is
Flex
;
});
}
void
applyParentData
(
RenderObject
renderObject
)
{
assert
(
renderObject
.
parentData
is
FlexParentData
);
final
FlexParentData
parentData
=
renderObject
.
parentData
;
if
(
parentData
.
flex
!=
flex
)
{
parentData
.
flex
=
flex
;
renderObject
.
markNeedsLayout
();
}
}
}
class
Paragraph
extends
LeafRenderObjectWidget
{
Paragraph
({
Key
key
,
this
.
text
})
:
super
(
key:
key
)
{
...
...
@@ -579,7 +646,51 @@ class StyledText extends StatelessComponent {
}
}
// TODO(abarth): Text
class
DefaultTextStyle
extends
InheritedWidget
{
DefaultTextStyle
({
Key
key
,
this
.
style
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
style
!=
null
);
assert
(
child
!=
null
);
}
final
TextStyle
style
;
static
TextStyle
of
(
BuildContext
context
)
{
DefaultTextStyle
result
=
context
.
inheritedWidgetOfType
(
DefaultTextStyle
);
return
result
?.
style
;
}
bool
updateShouldNotify
(
DefaultTextStyle
old
)
=>
style
!=
old
.
style
;
}
class
Text
extends
StatelessComponent
{
Text
(
this
.
data
,
{
Key
key
,
TextStyle
this
.
style
})
:
super
(
key:
key
)
{
assert
(
data
!=
null
);
}
final
String
data
;
final
TextStyle
style
;
Widget
build
(
BuildContext
context
)
{
TextSpan
text
=
new
PlainTextSpan
(
data
);
TextStyle
defaultStyle
=
DefaultTextStyle
.
of
(
context
);
TextStyle
combinedStyle
;
if
(
defaultStyle
!=
null
)
{
if
(
style
!=
null
)
combinedStyle
=
defaultStyle
.
merge
(
style
);
else
combinedStyle
=
defaultStyle
;
}
else
{
combinedStyle
=
style
;
}
if
(
combinedStyle
!=
null
)
text
=
new
StyledTextSpan
(
combinedStyle
,
[
text
]);
return
new
Paragraph
(
text:
text
);
}
}
class
Image
extends
LeafRenderObjectWidget
{
Image
({
...
...
packages/flutter/lib/src/fn3/framework.dart
View file @
fb4a87ad
...
...
@@ -105,7 +105,11 @@ abstract class StatelessComponent extends Widget {
/// Returns another Widget out of which this StatelessComponent is built.
/// Typically that Widget will have been configured with further children,
/// such that really this function returns a tree of configuration.
Widget
build
();
///
/// The given build context object contains information about the location in
/// the tree at which this component is being built. For example, the context
/// provides the set of inherited widgets for this location in the tree.
Widget
build
(
BuildContext
context
);
}
/// StatefulComponents provide the configuration for
...
...
@@ -162,7 +166,41 @@ abstract class ComponentState<T extends StatefulComponent> {
/// Returns another Widget out of which this StatefulComponent is built.
/// Typically that Widget will have been configured with further children,
/// such that really this function returns a tree of configuration.
Widget
build
();
///
/// The given build context object contains information about the location in
/// the tree at which this component is being built. For example, the context
/// provides the set of inherited widgets for this location in the tree.
Widget
build
(
BuildContext
context
);
}
abstract
class
ProxyWidget
extends
StatelessComponent
{
const
ProxyWidget
({
Key
key
,
Widget
this
.
child
})
:
super
(
key:
key
);
final
Widget
child
;
Widget
build
(
BuildContext
context
)
=>
child
;
}
abstract
class
ParentDataWidget
extends
ProxyWidget
{
ParentDataWidget
({
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
/// Subclasses should override this function to ensure that they are placed
/// inside widgets that expect them.
///
/// The given ancestor is the first RenderObjectWidget ancestor of this widget.
void
debugValidateAncestor
(
RenderObjectWidget
ancestor
);
void
applyParentData
(
RenderObject
renderObject
);
}
abstract
class
InheritedWidget
extends
ProxyWidget
{
const
InheritedWidget
({
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
InheritedElement
createElement
()
=>
new
InheritedElement
(
this
);
bool
updateShouldNotify
(
InheritedWidget
oldWidget
);
}
bool
_canUpdate
(
Widget
oldWidget
,
Widget
newWidget
)
{
...
...
@@ -180,11 +218,15 @@ typedef void ElementVisitor(Element element);
const
Object
_uniqueChild
=
const
Object
();
abstract
class
BuildContext
{
InheritedWidget
inheritedWidgetOfType
(
Type
targetType
);
}
/// Elements are the instantiations of Widget configurations.
///
/// Elements can, in principle, have children. Only subclasses of
/// RenderObjectElement are allowed to have more than one child.
abstract
class
Element
<
T
extends
Widget
>
{
abstract
class
Element
<
T
extends
Widget
>
implements
BuildContext
{
Element
(
T
widget
)
:
_widget
=
widget
{
assert
(
_widget
!=
null
);
}
...
...
@@ -355,9 +397,24 @@ abstract class Element<T extends Widget> {
assert
(
_depth
!=
null
);
assert
(()
{
_debugLifecycleState
=
_ElementLifecycle
.
defunct
;
return
true
;
});
}
Set
<
Type
>
_dependencies
;
InheritedWidget
inheritedWidgetOfType
(
Type
targetType
)
{
if
(
_dependencies
==
null
)
_dependencies
=
new
Set
<
Type
>();
_dependencies
.
add
(
targetType
);
Element
ancestor
=
_parent
;
while
(
ancestor
!=
null
&&
ancestor
.
_widget
.
runtimeType
!=
targetType
)
ancestor
=
ancestor
.
_parent
;
return
ancestor
.
_widget
;
}
void
dependenciesChanged
()
{
assert
(
false
);
}
}
typedef
Widget
WidgetBuilder
(
);
typedef
Widget
WidgetBuilder
(
BuildContext
context
);
typedef
void
BuildScheduler
(
BuildableElement
element
);
/// Base class for the instantiation of StatelessComponent and StatefulComponent
...
...
@@ -393,7 +450,7 @@ abstract class BuildableElement<T extends Widget> extends Element<T> {
_dirty
=
false
;
Widget
built
;
try
{
built
=
_builder
();
built
=
_builder
(
this
);
assert
(
built
!=
null
);
}
catch
(
e
,
stack
)
{
_debugReportException
(
'building
$this
'
,
e
,
stack
);
...
...
@@ -428,10 +485,14 @@ abstract class BuildableElement<T extends Widget> extends Element<T> {
super
.
unmount
();
_dirty
=
false
;
// so that we don't get rebuilt even if we're already marked dirty
}
void
dependenciesChanged
()
{
markNeedsBuild
();
}
}
/// Instantiation of StatelessComponent widgets.
class
StatelessComponentElement
extends
BuildableElement
<
StatelessComponent
>
{
class
StatelessComponentElement
<
T
extends
StatelessComponent
>
extends
BuildableElement
<
T
>
{
StatelessComponentElement
(
StatelessComponent
widget
)
:
super
(
widget
)
{
_builder
=
_widget
.
build
;
}
...
...
@@ -474,6 +535,52 @@ class StatefulComponentElement extends BuildableElement<StatefulComponent> {
}
}
class
ParentDataElement
extends
StatelessComponentElement
<
ParentDataWidget
>
{
ParentDataElement
(
ParentDataWidget
widget
)
:
super
(
widget
);
void
update
(
ParentDataWidget
newWidget
)
{
ParentDataWidget
oldWidget
=
_widget
;
super
.
update
(
newWidget
);
assert
(
_widget
==
newWidget
);
if
(
_widget
!=
oldWidget
)
_notifyDescendants
();
}
void
_notifyDescendants
()
{
void
notifyChildren
(
Element
child
)
{
if
(
child
is
RenderObjectElement
)
child
.
updateParentData
(
_widget
);
else
if
(
child
is
!
ParentDataElement
)
child
.
visitChildren
(
notifyChildren
);
}
visitChildren
(
notifyChildren
);
}
}
class
InheritedElement
extends
StatelessComponentElement
<
InheritedWidget
>
{
InheritedElement
(
InheritedWidget
widget
)
:
super
(
widget
);
void
update
(
StatelessComponent
newWidget
)
{
InheritedWidget
oldWidget
=
_widget
;
super
.
update
(
newWidget
);
assert
(
_widget
==
newWidget
);
if
(
_widget
.
updateShouldNotify
(
oldWidget
))
_notifyDescendants
();
}
void
_notifyDescendants
()
{
final
Type
ourRuntimeType
=
runtimeType
;
void
notifyChildren
(
Element
child
)
{
if
(
child
.
_dependencies
!=
null
&&
child
.
_dependencies
.
contains
(
ourRuntimeType
))
child
.
dependenciesChanged
();
if
(
child
.
runtimeType
!=
ourRuntimeType
)
child
.
visitChildren
(
notifyChildren
);
}
visitChildren
(
notifyChildren
);
}
}
/// Base class for instantiations of RenderObjectWidget subclasses
abstract
class
RenderObjectElement
<
T
extends
RenderObjectWidget
>
extends
Element
<
T
>
{
RenderObjectElement
(
T
widget
)
...
...
@@ -490,6 +597,16 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Element
return
ancestor
;
}
ParentDataElement
_findAncestorParentDataElement
()
{
Element
ancestor
=
_parent
;
while
(
ancestor
!=
null
&&
ancestor
is
!
RenderObjectElement
)
{
if
(
ancestor
is
ParentDataElement
)
return
ancestor
;
ancestor
=
ancestor
.
_parent
;
}
return
null
;
}
static
Map
<
RenderObject
,
RenderObjectElement
>
_registry
=
new
Map
<
RenderObject
,
RenderObjectElement
>();
static
Iterable
<
RenderObjectElement
>
getElementsForRenderObject
(
RenderObject
renderObject
)
sync
*
{
Element
target
=
_registry
[
renderObject
];
...
...
@@ -507,10 +624,13 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Element
assert
(
_ancestorRenderObjectElement
==
null
);
_ancestorRenderObjectElement
=
_findAncestorRenderObjectElement
();
_ancestorRenderObjectElement
?.
insertChildRenderObject
(
renderObject
,
slot
);
ParentDataElement
parentDataElement
=
_findAncestorParentDataElement
();
if
(
parentDataElement
!=
null
)
updateParentData
(
parentDataElement
.
_widget
);
}
void
update
(
T
newWidget
)
{
Widget
oldWidget
=
_widget
;
RenderObject
Widget
oldWidget
=
_widget
;
super
.
update
(
newWidget
);
assert
(
_widget
==
newWidget
);
_widget
.
updateRenderObject
(
renderObject
,
oldWidget
);
...
...
@@ -522,6 +642,14 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Element
_registry
.
remove
(
renderObject
);
}
void
updateParentData
(
ParentDataWidget
parentData
)
{
assert
(()
{
parentData
.
debugValidateAncestor
(
_ancestorRenderObjectElement
.
_widget
);
return
true
;
});
parentData
.
applyParentData
(
renderObject
);
}
void
detachRenderObject
()
{
if
(
_ancestorRenderObjectElement
!=
null
)
{
_ancestorRenderObjectElement
.
removeChildRenderObject
(
renderObject
);
...
...
@@ -590,7 +718,15 @@ class OneChildRenderObjectElement<T extends OneChildRenderObjectWidget> extends
class
MultiChildRenderObjectElement
<
T
extends
MultiChildRenderObjectWidget
>
extends
RenderObjectElement
<
T
>
{
MultiChildRenderObjectElement
(
T
widget
)
:
super
(
widget
);
// TODO(ianh): implement
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
// TODO(ianh): implement
assert
(
false
);
}
void
removeChildRenderObject
(
RenderObject
child
)
{
// TODO(ianh): implement
assert
(
false
);
}
}
typedef
void
WidgetsExceptionHandler
(
String
context
,
dynamic
exception
,
StackTrace
stack
);
...
...
packages/unit/test/fn3/render_object_widget_test.dart
View file @
fb4a87ad
...
...
@@ -11,7 +11,7 @@ final BoxDecoration kBoxDecorationC = new BoxDecoration();
class
TestComponent
extends
StatelessComponent
{
const
TestComponent
({
this
.
child
});
final
Widget
child
;
Widget
build
()
=>
child
;
Widget
build
(
BuildContext
context
)
=>
child
;
}
void
main
(
)
{
...
...
packages/unit/test/fn3/stateful_component_test.dart
View file @
fb4a87ad
...
...
@@ -23,7 +23,7 @@ class TestComponentState extends ComponentState<TestComponentConfig> {
});
}
Widget
build
()
{
Widget
build
(
BuildContext
context
)
{
return
_showLeft
?
config
.
left
:
config
.
right
;
}
}
...
...
@@ -34,7 +34,7 @@ final BoxDecoration kBoxDecorationB = new BoxDecoration();
class
TestBuildCounter
extends
StatelessComponent
{
static
int
buildCount
=
0
;
Widget
build
()
{
Widget
build
(
BuildContext
context
)
{
++
buildCount
;
return
new
DecoratedBox
(
decoration:
kBoxDecorationA
);
}
...
...
packages/unit/test/fn3/widget_tester.dart
View file @
fb4a87ad
...
...
@@ -15,7 +15,7 @@ class RootComponentState extends ComponentState<RootComponent> {
});
}
}
Widget
build
()
=>
child
;
Widget
build
(
BuildContext
context
)
=>
child
;
}
const
Object
_rootSlot
=
const
Object
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment