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
025c43de
Commit
025c43de
authored
Feb 13, 2016
by
Adam Barth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds documentation to the layering examples
parent
aba27211
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
254 additions
and
73 deletions
+254
-73
canvas.dart
examples/layers/raw/canvas.dart
+24
-2
hello_world.dart
examples/layers/raw/hello_world.dart
+69
-12
spinning_square.dart
examples/layers/raw/spinning_square.dart
+48
-37
text.dart
examples/layers/raw/text.dart
+29
-6
autolayout.dart
examples/layers/rendering/autolayout.dart
+2
-1
custom_coordinate_systems.dart
examples/layers/rendering/custom_coordinate_systems.dart
+3
-0
flex_layout.dart
examples/layers/rendering/flex_layout.dart
+3
-0
hello_world.dart
examples/layers/rendering/hello_world.dart
+8
-0
spinning_square.dart
examples/layers/rendering/spinning_square.dart
+24
-8
touch_input.dart
examples/layers/rendering/touch_input.dart
+44
-7
No files found.
examples/layers/raw/canvas.dart
View file @
025c43de
...
...
@@ -2,19 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This example shows how to use the ui.Canvas interface to draw various shapes
// with gradients and transforms.
import
'dart:ui'
as
ui
;
import
'dart:math'
as
math
;
import
'dart:typed_data'
;
ui
.
Picture
paint
(
ui
.
Rect
paintBounds
)
{
// First we create a PictureRecorder to record the commands we're going to
// feed in the canvas. The PictureRecorder will eventually produce a Picture,
// which is an immutable record of those commands.
ui
.
PictureRecorder
recorder
=
new
ui
.
PictureRecorder
();
// Next, we create a canvas from the recorder. The canvas is an interface
// which can receive drawing commands. The canvas interface is modeled after
// the SkCanvas interface from Skia. The paintBounds establishes a "cull rect"
// for the canvas, which lets the implementation discard any commands that
// are entirely outside this rectangle.
ui
.
Canvas
canvas
=
new
ui
.
Canvas
(
recorder
,
paintBounds
);
ui
.
Size
size
=
paintBounds
.
size
;
ui
.
Paint
paint
=
new
ui
.
Paint
();
canvas
.
drawPaint
(
new
ui
.
Paint
()..
color
=
const
ui
.
Color
(
0xFFFFFFFF
));
ui
.
Size
size
=
paintBounds
.
size
;
ui
.
Point
mid
=
size
.
center
(
ui
.
Point
.
origin
);
double
radius
=
size
.
shortestSide
/
2.0
;
canvas
.
drawPaint
(
new
ui
.
Paint
()..
color
=
const
ui
.
Color
(
0xFFFFFFFF
));
canvas
.
save
();
canvas
.
translate
(-
mid
.
x
/
2.0
,
ui
.
window
.
size
.
height
*
2.0
);
...
...
@@ -46,6 +59,11 @@ ui.Picture paint(ui.Rect paintBounds) {
canvas
.
restore
();
canvas
.
translate
(
0.0
,
50.0
);
// A DrawLooper is a powerful painting primitive that lets you apply several
// blending and filtering passes over a sequence of commands "in a loop". For
// example, the looper below draws the circle tree times, once with a blur,
// then with a gradient blend, and finally with just an offset.
ui
.
LayerDrawLooperBuilder
builder
=
new
ui
.
LayerDrawLooperBuilder
()
..
addLayerOnTop
(
new
ui
.
DrawLooperLayerInfo
()
...
...
@@ -90,6 +108,10 @@ ui.Picture paint(ui.Rect paintBounds) {
paint
.
drawLooper
=
builder
.
build
();
canvas
.
drawCircle
(
ui
.
Point
.
origin
,
radius
,
paint
);
// When we're done issuing painting commands, we end the recording an receive
// a Picture, which is an immutable record of the commands we've issued. You
// can draw a Picture into another canvas or include it as part of a
// composited scene.
return
recorder
.
endRecording
();
}
...
...
examples/layers/raw/hello_world.dart
View file @
025c43de
...
...
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This example shows how to put some pixels on the screen using the raw
// interface to the engine.
import
'dart:ui'
as
ui
;
import
'dart:typed_data'
;
...
...
@@ -12,18 +15,38 @@ import 'package:sky_services/pointer/pointer.mojom.dart';
ui
.
Color
color
;
ui
.
Picture
paint
(
ui
.
Rect
paintBounds
)
{
// First we create a PictureRecorder to record the commands we're going to
// feed in the canvas. The PictureRecorder will eventually produce a Picture,
// which is an immutable record of those commands.
ui
.
PictureRecorder
recorder
=
new
ui
.
PictureRecorder
();
// Next, we create a canvas from the recorder. The canvas is an interface
// which can receive drawing commands. The canvas interface is modeled after
// the SkCanvas interface from Skia. The paintBounds establishes a "cull rect"
// for the canvas, which lets the implementation discard any commands that
// are entirely outside this rectangle.
ui
.
Canvas
canvas
=
new
ui
.
Canvas
(
recorder
,
paintBounds
);
ui
.
Size
size
=
paintBounds
.
size
;
double
radius
=
size
.
shortestSide
*
0.45
;
ui
.
Paint
paint
=
new
ui
.
Paint
()..
color
=
color
;
canvas
.
drawCircle
(
size
.
center
(
ui
.
Point
.
origin
),
radius
,
paint
);
// The commands draw a circle in the center of the screen.
ui
.
Size
size
=
paintBounds
.
size
;
canvas
.
drawCircle
(
size
.
center
(
ui
.
Point
.
origin
),
size
.
shortestSide
*
0.45
,
new
ui
.
Paint
()..
color
=
color
);
// When we're done issuing painting commands, we end the recording an receive
// a Picture, which is an immutable record of the commands we've issued. You
// can draw a Picture into another canvas or include it as part of a
// composited scene.
return
recorder
.
endRecording
();
}
ui
.
Scene
composite
(
ui
.
Picture
picture
,
ui
.
Rect
paintBounds
)
{
// The device pixel ratio gives an approximate ratio of the size of pixels on
// the device's screen to "normal" sized pixels. We commonly work in logical
// pixels, which are then scalled by the device pixel ratio before being drawn
// on the screen.
final
double
devicePixelRatio
=
ui
.
window
.
devicePixelRatio
;
ui
.
Rect
sceneBounds
=
new
ui
.
Rect
.
fromLTWH
(
0.0
,
...
...
@@ -31,49 +54,83 @@ ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
ui
.
window
.
size
.
width
*
devicePixelRatio
,
ui
.
window
.
size
.
height
*
devicePixelRatio
);
// This transform scales the x and y coordinates by the devicePixelRatio.
Float64List
deviceTransform
=
new
Float64List
(
16
)
..[
0
]
=
devicePixelRatio
..[
5
]
=
devicePixelRatio
..[
10
]
=
1.0
..[
15
]
=
1.0
;
// We build a very simple scene graph with two nodes. The root node is a
// transform that scale its children by the device pixel ratio. This transform
// lets us paint in "logical" pixels which are converted to device pixels by
// this scaling operation.
ui
.
SceneBuilder
sceneBuilder
=
new
ui
.
SceneBuilder
(
sceneBounds
)
..
pushTransform
(
deviceTransform
)
..
addPicture
(
ui
.
Offset
.
zero
,
picture
)
..
pop
();
// When we're done recording the scene, we call build() to obtain an immutable
// record of the scene we've recorded.
return
sceneBuilder
.
build
();
}
void
beginFrame
(
Duration
timeStamp
)
{
ui
.
Rect
paintBounds
=
ui
.
Point
.
origin
&
ui
.
window
.
size
;
// First, record a picture with our painting commands.
ui
.
Picture
picture
=
paint
(
paintBounds
);
// Second, include that picture in a scene graph.
ui
.
Scene
scene
=
composite
(
picture
,
paintBounds
);
// Third, instruct the engine to render that scene graph.
ui
.
window
.
render
(
scene
);
}
void
handlePopRoute
(
)
{
print
(
'Pressed back button.'
);
}
// Pointer input arrives as an array of bytes. The format for the data is
// defined by pointer.mojom, which generates serializes and parsers for a
// number of languages, including Dart, C++, Java, and Go.
void
handlePointerPacket
(
ByteData
serializedPacket
)
{
// We wrap the byte data up into a Mojo Message object, which we then
// deserialize according to the mojom definition.
bindings
.
Message
message
=
new
bindings
.
Message
(
serializedPacket
,
<
core
.
MojoHandle
>[],
serializedPacket
.
lengthInBytes
,
0
);
PointerPacket
packet
=
PointerPacket
.
deserialize
(
message
);
// The deserialized pointer packet contains a number of pointer movements,
// which we iterate through and process.
for
(
Pointer
pointer
in
packet
.
pointers
)
{
if
(
pointer
.
type
==
PointerType
.
down
)
{
color
=
new
ui
.
Color
.
fromARGB
(
255
,
0
,
0
,
255
);
// If the pointer went down, we change the color of the circle to blue.
color
=
const
ui
.
Color
(
0xFF0000FF
);
// Rather than calling paint() synchronously, we ask the engine to
// schedule a frame. The engine will call onBeginFrame when it is actually
// time to produce the frame.
ui
.
window
.
scheduleFrame
();
}
else
if
(
pointer
.
type
==
PointerType
.
up
)
{
color
=
new
ui
.
Color
.
fromARGB
(
255
,
0
,
255
,
0
);
// Similarly, if the pointer went up, we change the color of the circle to
// green and schedule a frame. It's harmless to call scheduleFrame many
// times because the engine will ignore redundant requests up until the
// point where the engine calls onBeginFrame, which signals the boundary
// between one frame and another.
color
=
const
ui
.
Color
(
0xFF00FF00
);
ui
.
window
.
scheduleFrame
();
}
}
}
// This function is the primary entry point to your application. The engine
// calls main() as soon as it has loaded your code.
void
main
(
)
{
// Print statements go either go to stdout or to the system log, as
// appropriate for the operating system.
print
(
'Hello, world'
);
color
=
new
ui
.
Color
.
fromARGB
(
255
,
0
,
255
,
0
);
color
=
const
ui
.
Color
(
0xFF00FF00
);
// The engine calls onBeginFrame whenever it wants us to produce a frame.
ui
.
window
.
onBeginFrame
=
beginFrame
;
ui
.
window
.
onPopRoute
=
handlePopRoute
;
// The engine calls onPointerPacket whenever it had updated information about
// the pointers directed at our app.
ui
.
window
.
onPointerPacket
=
handlePointerPacket
;
// Here we kick off the whole process by asking the engine to schedule a new
// frame. The engine will eventually call onBeginFrame when it is time for us
// to actually produce the frame.
ui
.
window
.
scheduleFrame
();
}
examples/layers/raw/spinning_square.dart
View file @
025c43de
...
...
@@ -2,49 +2,60 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:developer'
;
// This example shows how to perform a simple animation using the raw interface
// to the engine.
import
'dart:math'
as
math
;
import
'dart:typed_data'
;
import
'dart:ui'
as
ui
;
Duration
timeBase
=
null
;
void
beginFrame
(
Duration
timeStamp
)
{
Timeline
.
timeSync
(
'beginFrame'
,
()
{
if
(
timeBase
==
null
)
timeBase
=
timeStamp
;
double
delta
=
(
timeStamp
-
timeBase
).
inMicroseconds
/
Duration
.
MICROSECONDS_PER_MILLISECOND
;
// paint
ui
.
Rect
paintBounds
=
ui
.
Point
.
origin
&
ui
.
window
.
size
;
ui
.
PictureRecorder
recorder
=
new
ui
.
PictureRecorder
();
ui
.
Canvas
canvas
=
new
ui
.
Canvas
(
recorder
,
paintBounds
);
canvas
.
translate
(
paintBounds
.
width
/
2.0
,
paintBounds
.
height
/
2.0
);
canvas
.
rotate
(
math
.
PI
*
delta
/
1800
);
canvas
.
drawRect
(
new
ui
.
Rect
.
fromLTRB
(-
100.0
,
-
100.0
,
100.0
,
100.0
),
new
ui
.
Paint
()..
color
=
const
ui
.
Color
.
fromARGB
(
255
,
0
,
255
,
0
));
ui
.
Picture
picture
=
recorder
.
endRecording
();
// composite
final
double
devicePixelRatio
=
ui
.
window
.
devicePixelRatio
;
ui
.
Rect
sceneBounds
=
new
ui
.
Rect
.
fromLTWH
(
0.0
,
0.0
,
ui
.
window
.
size
.
width
*
devicePixelRatio
,
ui
.
window
.
size
.
height
*
devicePixelRatio
);
Float64List
deviceTransform
=
new
Float64List
(
16
)
..[
0
]
=
devicePixelRatio
..[
5
]
=
devicePixelRatio
..[
10
]
=
1.0
..[
15
]
=
1.0
;
ui
.
SceneBuilder
sceneBuilder
=
new
ui
.
SceneBuilder
(
sceneBounds
)
..
pushTransform
(
deviceTransform
)
..
addPicture
(
ui
.
Offset
.
zero
,
picture
)
..
pop
();
ui
.
window
.
render
(
sceneBuilder
.
build
());
});
// The timeStamp argument to beginFrame indicates the timing information we
// should use to clock our animations. It's important to use timeStamp rather
// than reading the system time because we want all the parts of the system to
// coordinate the timings of their animations. If each component read the
// system clock independently, the animations that we processed later would be
// slightly ahead of the animations we processed earlier.
// PAINT
ui
.
Rect
paintBounds
=
ui
.
Point
.
origin
&
ui
.
window
.
size
;
ui
.
PictureRecorder
recorder
=
new
ui
.
PictureRecorder
();
ui
.
Canvas
canvas
=
new
ui
.
Canvas
(
recorder
,
paintBounds
);
canvas
.
translate
(
paintBounds
.
width
/
2.0
,
paintBounds
.
height
/
2.0
);
// Here we determine the rotation according to the timeStamp given to us by
// the engine.
double
t
=
timeStamp
.
inMicroseconds
/
Duration
.
MICROSECONDS_PER_MILLISECOND
/
1800.0
;
canvas
.
rotate
(
math
.
PI
*
(
t
%
1.0
));
canvas
.
drawRect
(
new
ui
.
Rect
.
fromLTRB
(-
100.0
,
-
100.0
,
100.0
,
100.0
),
new
ui
.
Paint
()..
color
=
const
ui
.
Color
.
fromARGB
(
255
,
0
,
255
,
0
));
ui
.
Picture
picture
=
recorder
.
endRecording
();
// COMPOSITE
final
double
devicePixelRatio
=
ui
.
window
.
devicePixelRatio
;
ui
.
Rect
sceneBounds
=
new
ui
.
Rect
.
fromLTWH
(
0.0
,
0.0
,
ui
.
window
.
size
.
width
*
devicePixelRatio
,
ui
.
window
.
size
.
height
*
devicePixelRatio
);
Float64List
deviceTransform
=
new
Float64List
(
16
)
..[
0
]
=
devicePixelRatio
..[
5
]
=
devicePixelRatio
..[
10
]
=
1.0
..[
15
]
=
1.0
;
ui
.
SceneBuilder
sceneBuilder
=
new
ui
.
SceneBuilder
(
sceneBounds
)
..
pushTransform
(
deviceTransform
)
..
addPicture
(
ui
.
Offset
.
zero
,
picture
)
..
pop
();
ui
.
window
.
render
(
sceneBuilder
.
build
());
// After rendering the current frame of the animation, we ask the engine to
// schedule another frame. The engine will call beginFrame again when its time
// to produce the next frame.
ui
.
window
.
scheduleFrame
();
}
...
...
examples/layers/raw/text.dart
View file @
025c43de
...
...
@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This example shows how to draw some bi-directional text using the raw
// interface to the engine.
import
'dart:ui'
as
ui
;
import
'dart:typed_data'
;
// A paragraph represents a rectangular region that contains some text.
ui
.
Paragraph
paragraph
;
ui
.
Picture
paint
(
ui
.
Rect
paintBounds
)
{
...
...
@@ -15,8 +19,9 @@ ui.Picture paint(ui.Rect paintBounds) {
canvas
.
drawRect
(
new
ui
.
Rect
.
fromLTRB
(-
100.0
,
-
100.0
,
100.0
,
100.0
),
new
ui
.
Paint
()..
color
=
const
ui
.
Color
.
fromARGB
(
255
,
0
,
255
,
0
));
canvas
.
translate
(
paragraph
.
maxWidth
/
-
2.0
,
(
paragraph
.
maxWidth
/
2.0
)
-
125
);
paragraph
.
paint
(
canvas
,
ui
.
Offset
.
zero
);
// The paint method of Pargraph draws the contents of the paragraph unto the
// given canvas.
paragraph
.
paint
(
canvas
,
new
ui
.
Offset
(
paragraph
.
maxWidth
/
-
2.0
,
(
paragraph
.
maxWidth
/
2.0
)
-
125
));
return
recorder
.
endRecording
();
}
...
...
@@ -49,19 +54,37 @@ void beginFrame(Duration timeStamp) {
}
void
main
(
)
{
// To create a paragraph of text, we use ParagraphBuilder.
ui
.
ParagraphBuilder
builder
=
new
ui
.
ParagraphBuilder
()
// We first push a style that turns the text blue.
..
pushStyle
(
new
ui
.
TextStyle
(
color:
const
ui
.
Color
(
0xFF0000FF
)))
..
addText
(
"Hello, "
)
..
addText
(
'Hello, '
)
// The next run of text will be bold.
..
pushStyle
(
new
ui
.
TextStyle
(
fontWeight:
ui
.
FontWeight
.
bold
))
..
addText
(
"world. "
)
..
addText
(
'world. '
)
// The pop() command signals the end of the bold styling.
..
pop
()
..
addText
(
"هذا هو قليلا طويلة من النص الذي يجب التفاف ."
)
// We add text to the paragraph in logical order. The paragraph object
// understands bi-directional text and will compute the visual ordering
// during layout.
..
addText
(
'هذا هو قليلا طويلة من النص الذي يجب التفاف .'
)
// The second pop() removes the blue color.
..
pop
()
..
addText
(
" و أكثر قليلا لجعله أطول. "
);
// We can add more text with the default styling.
..
addText
(
' و أكثر قليلا لجعله أطول. '
)
..
addText
(
'สวัสดี'
);
// When we're done adding styles and text, we build the Paragraph object, at
// which time we can apply styling that affects the entire paragraph, such as
// left, right, or center alignment. Once built, the contents of the paragraph
// cannot be altered, but sizing and positioning information can be updated.
paragraph
=
builder
.
build
(
new
ui
.
ParagraphStyle
())
// Next, we supply a maximum width that the text is permitted to occupy.
..
maxWidth
=
180.0
// ... and we ask the paragraph to the visual position of each its glyphs as
// well as its overall size, subject to its sizing constraints.
..
layout
();
// Finally, we register our beginFrame callback and kick off the first frame.
ui
.
window
.
onBeginFrame
=
beginFrame
;
ui
.
window
.
scheduleFrame
();
}
examples/layers/rendering/autolayout.dart
View file @
025c43de
...
...
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
;
// This example shows how to use the Cassowary autolayout system directly in the
// underlying render tree.
import
'package:cassowary/cassowary.dart'
as
al
;
import
'package:flutter/rendering.dart'
;
...
...
examples/layers/rendering/custom_coordinate_systems.dart
View file @
025c43de
...
...
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This example shows how to build a render tree with a non-cartesian coordinate
// system. Most of the guts of this examples are in src/sector_layout.dart.
import
'package:flutter/rendering.dart'
;
import
'src/sector_layout.dart'
;
...
...
examples/layers/rendering/flex_layout.dart
View file @
025c43de
...
...
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This example shows how to use flex layout directly in the underlying render
// tree.
import
'package:flutter/rendering.dart'
;
import
'src/solid_color_box.dart'
;
...
...
examples/layers/rendering/hello_world.dart
View file @
025c43de
...
...
@@ -2,12 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This example shows how to show the text 'Hello, world.' using the underlying
// render tree.
import
'package:flutter/rendering.dart'
;
void
main
(
)
{
// We use RenderingFlutterBinding to attach the render tree to the window.
new
RenderingFlutterBinding
(
// The root of our render tree is a RenderPositionedBox, which centers its
// child both vertically and horizontally.
root:
new
RenderPositionedBox
(
alignment:
const
FractionalOffset
(
0.5
,
0.5
),
// We use a RenderParagraph to display the text "Hello, world." without
// any explicit styling.
child:
new
RenderParagraph
(
new
PlainTextSpan
(
'Hello, world.'
))
)
);
...
...
examples/layers/rendering/spinning_square.dart
View file @
025c43de
...
...
@@ -2,43 +2,59 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This example shows how to perform a simple animation using the underlying
// render tree.
import
'dart:math'
as
math
;
import
'package:flutter/animation.dart'
;
import
'package:flutter/rendering.dart'
;
void
main
(
)
{
//
A green box..
.
//
We first create a render object that represents a green box
.
RenderBox
green
=
new
RenderDecoratedBox
(
decoration:
const
BoxDecoration
(
backgroundColor:
const
Color
(
0xFF00FF00
))
);
// of a certain size...
// Second, we wrap that green box in a render object that forces the green box
// to have a specific size.
RenderBox
square
=
new
RenderConstrainedBox
(
additionalConstraints:
const
BoxConstraints
.
tightFor
(
width:
200.0
,
height:
200.0
),
child:
green
);
// With a given rotation (starts off as the identity transform)...
// Third, we wrap the sized green square in a render object that applies rotation
// transform before painting its child. Each frame of the animation, we'll
// update the transform of this render object to cause the green square to
// spin.
RenderTransform
spin
=
new
RenderTransform
(
transform:
new
Matrix4
.
identity
(),
alignment:
const
FractionalOffset
(
0.5
,
0.5
),
child:
square
);
//
centered
...
//
Finally, we center the spinning green square
...
RenderBox
root
=
new
RenderPositionedBox
(
alignment:
const
FractionalOffset
(
0.5
,
0.5
),
child:
spin
);
//
on the screen
.
//
and attach it to the window
.
new
RenderingFlutterBinding
(
root:
root
);
// A repeating animation every 1800 milliseconds...
// To make the square spin, we use an animation that repeats every 1800
// milliseconds.
AnimationController
animation
=
new
AnimationController
(
duration:
const
Duration
(
milliseconds:
1800
)
)..
repeat
();
// From 0.0 to math.PI.
// The animation will produce a value between 0.0 and 1.0 each frame, but we
// want to rotate the square using a value between 0.0 and math.PI. To change
// the range of the animation, we use a Tween.
Tween
<
double
>
tween
=
new
Tween
<
double
>(
begin:
0.0
,
end:
math
.
PI
);
// We add a listener to the animation, which will be called every time the
// animation ticks.
animation
.
addListener
(()
{
// Each frame of the animation, set the rotation of the square.
// This code runs every tick of the animation and sets a new transform on
// the "spin" render object by evaluating the tween on the current value
// of the animation. Setting this value will mark a number of dirty bits
// inside the render tree, which cause the render tree to repaint with the
// new transform value this frame.
spin
.
transform
=
new
Matrix4
.
rotationZ
(
tween
.
evaluate
(
animation
));
});
}
examples/layers/rendering/touch_input.dart
View file @
025c43de
...
...
@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
// This example shows how to use process input events in the underlying render
// tree.
import
'package:flutter/material.dart'
;
// Imported just for its color palette.
import
'package:flutter/rendering.dart'
;
// Material design colors. :p
...
...
@@ -34,12 +37,23 @@ class Dot {
}
/// A render object that draws dots under each pointer.
class
RenderDots
extends
Render
Constrained
Box
{
RenderDots
()
:
super
(
additionalConstraints:
const
BoxConstraints
.
expand
())
;
class
RenderDots
extends
RenderBox
{
RenderDots
();
/// State to remember which dots to paint.
final
Map
<
int
,
Dot
>
_dots
=
<
int
,
Dot
>{};
/// Indicates that the size of this render object depends only on the
/// layout constraints provided by the parent.
bool
get
sizedByParent
=>
true
;
/// By selecting the biggest value permitted by the incomming constraints
/// during layout, this function makes this render object as large as
/// possible (i.e., fills the entire screen).
void
performResize
()
{
size
=
constraints
.
biggest
;
}
/// Makes this render object hittable so that it receives pointer events.
bool
hitTestSelf
(
Point
position
)
=>
true
;
...
...
@@ -49,6 +63,10 @@ class RenderDots extends RenderConstrainedBox {
if
(
event
is
PointerDownEvent
)
{
Color
color
=
_kColors
[
event
.
pointer
.
remainder
(
_kColors
.
length
)];
_dots
[
event
.
pointer
]
=
new
Dot
(
color:
color
)..
update
(
event
);
// We call markNeedsPaint to indicate that our painting commands have
// changed and that paint needs to be called before displaying a new frame
// to the user. It's harmless to call markNeedsPaint multiple times
// because the render tree will ignore redundant calls.
markNeedsPaint
();
}
else
if
(
event
is
PointerUpEvent
||
event
is
PointerCancelEvent
)
{
_dots
.
remove
(
event
.
pointer
);
...
...
@@ -62,31 +80,50 @@ class RenderDots extends RenderConstrainedBox {
/// Issues new painting commands.
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
final
Canvas
canvas
=
context
.
canvas
;
// The "size" property indicates the size of that this render box was
// alotted during layout. Here we paint our bounds white. Notice that we're
// located at "offset" from the origin of the canvas' coordinate system.
// Passing offset during the render tree's paint walk is an optimization to
// avoid having to change the origin of the canvas's coordinate system too
// often.
canvas
.
drawRect
(
offset
&
size
,
new
Paint
()..
color
=
const
Color
(
0xFFFFFFFF
));
// We iterate through our model and paint each dot.
for
(
Dot
dot
in
_dots
.
values
)
dot
.
paint
(
canvas
,
offset
);
super
.
paint
(
context
,
offset
);
}
}
void
main
(
)
{
// Create some styled text to tell the user to interact with the app.
RenderParagraph
paragraph
=
new
RenderParagraph
(
new
StyledTextSpan
(
new
TextStyle
(
color:
Colors
.
black87
),
[
new
PlainTextSpan
(
"Touch me!"
)
]
<
TextSpan
>
[
new
PlainTextSpan
(
"Touch me!"
)
]
)
);
// A stack is a render object that layers its children on top of each other.
// The bottom later is our RenderDots object, and on top of that we show the
// text.
RenderStack
stack
=
new
RenderStack
(
children:
<
RenderBox
>[
new
RenderDots
(),
paragraph
,
]
);
// Prevent the RenderParagraph from filling the whole screen so
// that it doesn't eat events.
// The "parentData" field of a render object is controlled by the render
// object's parent render object. Now that we've added the paragraph as a
// child of the RenderStack, the paragraph's parentData field has been
// populated with a StackParentData, which we can use to provide input to the
// stack's layout algorithm.
//
// We use the StackParentData of the paragraph to position the text in the top
// left corner of the screen.
final
StackParentData
paragraphParentData
=
paragraph
.
parentData
;
paragraphParentData
..
top
=
40.0
..
left
=
20.0
;
// Finally, we attach the render tree we've built to the screen.
new
RenderingFlutterBinding
(
root:
stack
);
}
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