浏览代码

Implement CardsDemo.

/main
Yuncong Zhang 6 年前
当前提交
dc7e8b0b
共有 10 个文件被更改,包括 2633 次插入15 次删除
  1. 164
      Runtime/rendering/proxy_box.cs
  2. 36
      Runtime/widgets/basic.cs
  3. 32
      Samples/UIWidgetsGallery/gallery/demo.cs
  4. 18
      Samples/UIWidgetsGallery/gallery/demos.cs
  5. 217
      Samples/UIWidgetsGallery/demo/material/cards_demo.cs
  6. 3
      Samples/UIWidgetsGallery/demo/material/cards_demo.cs.meta
  7. 1001
      Tests/Resources/india_chettinad_silk_maker.png
  8. 88
      Tests/Resources/india_chettinad_silk_maker.png.meta
  9. 1001
      Tests/Resources/india_thanjavur_market.png
  10. 88
      Tests/Resources/india_thanjavur_market.png.meta

164
Runtime/rendering/proxy_box.cs


this._debugPaint.strokeWidth = 2.0f;
this._debugPaint.style = PaintingStyle.stroke;
}
if (this._debugText == null) {
this._debugText = new TextPainter(
text: new TextSpan(

));
this._debugText.layout();
}
return true;
});
}

public override bool hitTest(HitTestResult result, Offset position = null) {
D.assert(position != null);
if (this._clipper != null) {
this._updateClip();
D.assert(this._clip != null);

properties.add(new DiagnosticsProperty<Offset>("origin", this.origin));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
properties.add(new DiagnosticsProperty<bool>("transformHitTests", this.transformHitTests));
}
}
public class RenderFittedBox : RenderProxyBox {
public RenderFittedBox(
BoxFit fit = BoxFit.contain,
Alignment alignment = null,
RenderBox child = null
) : base(child) {
D.assert(fit != null);
this._fit = fit;
this._alignment = alignment ?? Alignment.center;
}
Alignment _resolvedAlignment;
void _resolve() {
if (this._resolvedAlignment != null) {
return;
}
this._resolvedAlignment = this.alignment;
}
void _markNeedResolution() {
this._resolvedAlignment = null;
this.markNeedsPaint();
}
public BoxFit fit {
get { return this._fit; }
set {
D.assert(value != null);
if (this._fit == value) {
return;
}
this._fit = value;
this._clearPaintData();
this.markNeedsPaint();
}
}
BoxFit _fit;
public Alignment alignment {
get { return this._alignment; }
set {
D.assert(value != null);
if (this._alignment == value) {
return;
}
this._alignment = value;
this._clearPaintData();
this._markNeedResolution();
}
}
Alignment _alignment;
protected override void performLayout() {
if (this.child != null) {
this.child.layout(new BoxConstraints(), parentUsesSize: true);
this.size = this.constraints.constrainSizeAndAttemptToPreserveAspectRatio(this.child.size);
this._clearPaintData();
}
else {
this.size = this.constraints.smallest;
}
}
bool? _hasVisualOverflow;
Matrix3 _transform;
void _clearPaintData() {
this._hasVisualOverflow = null;
this._transform = null;
}
void _updatePaintData() {
if (this._transform != null) {
return;
}
if (this.child == null) {
this._hasVisualOverflow = false;
this._transform = Matrix3.I();
}
else {
this._resolve();
Size childSize = this.child.size;
FittedSizes sizes = FittedSizes.applyBoxFit(this._fit, childSize, this.size);
float scaleX = sizes.destination.width / sizes.source.width;
float scaleY = sizes.destination.height / sizes.source.height;
Rect sourceRect = this._resolvedAlignment.inscribe(sizes.source, Offset.zero & childSize);
Rect destinationRect = this._resolvedAlignment.inscribe(sizes.destination, Offset.zero & this.size);
this._hasVisualOverflow = sourceRect.width < childSize.width || sourceRect.height < childSize.height;
this._transform = Matrix3.makeTrans(destinationRect.left, destinationRect.top);
this._transform.postScale(scaleX, scaleY);
this._transform.postTranslate(-sourceRect.left, -sourceRect.top);
}
}
void _paintChildWithTransform(PaintingContext context, Offset offset) {
Offset childOffset = MatrixUtils.getAsTranslation(this._transform);
if (childOffset == null) {
context.pushTransform(this.needsCompositing, offset, this._transform, base.paint);
}
else {
base.paint(context, offset + childOffset);
}
}
public override void paint(PaintingContext context, Offset offset) {
if (this.size.isEmpty) {
return;
}
this._updatePaintData();
if (this.child != null) {
if (this._hasVisualOverflow == true) {
context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size,
this._paintChildWithTransform);
}
else {
this._paintChildWithTransform(context, offset);
}
}
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.size.isEmpty) {
return false;
}
this._updatePaintData();
Matrix3 inverse = Matrix3.I();
if (!this._transform.invert(inverse)) {
return false;
}
position = inverse.mapPoint(position);
return base.hitTestChildren(result, position: position);
}
public override void applyPaintTransform(RenderObject child, Matrix3 transform) {
if (this.size.isEmpty) {
transform.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
}
else {
this._updatePaintData();
transform.postConcat(this._transform);
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<BoxFit>("fit", this.fit));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
}
}

36
Runtime/widgets/basic.cs


}
}
public class FittedBox : SingleChildRenderObjectWidget {
public FittedBox(
Key key = null,
BoxFit fit = BoxFit.contain,
Alignment alignment = null,
Widget child = null
) : base(key: key, child: child) {
D.assert(fit != null);
this.fit = fit;
this.alignment = alignment ?? Alignment.center;
}
public readonly BoxFit fit;
public readonly Alignment alignment;
public override RenderObject createRenderObject(BuildContext context) {
return new RenderFittedBox(
fit: this.fit,
alignment: this.alignment
);
}
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
RenderFittedBox renderObject = _renderObject as RenderFittedBox;
renderObject.fit = this.fit;
renderObject.alignment = this.alignment;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<BoxFit>("fit", this.fit));
properties.add(new DiagnosticsProperty<Alignment>("alignment", this.alignment));
}
}
public class FractionalTranslation : SingleChildRenderObjectWidget {
public FractionalTranslation(Key key = null, Offset translation = null,
bool transformHitTests = true, Widget child = null) : base(key: key, child: child) {

32
Samples/UIWidgetsGallery/gallery/demo.cs


using Unity.UIWidgets.painting;
using Unity.UIWidgets.service;
using Unity.UIWidgets.widgets;
using UnityEngine;
class ComponentDemoTabData {
public class ComponentDemoTabData {
public ComponentDemoTabData(
Widget demoWidget = null,
string exampleCodeTag = null,

}
class TabbedComponentDemoScaffold : StatelessWidget {
public class TabbedComponentDemoScaffold : StatelessWidget {
public TabbedComponentDemoScaffold(
string title = null,
List<ComponentDemoTabData> demos = null,

}
class FullScreenCodeDialog : StatefulWidget {
public class FullScreenCodeDialog : StatefulWidget {
public FullScreenCodeDialog(Key key = null, string exampleCodeTag = null) : base(key: key) {
this.exampleCodeTag = exampleCodeTag;
}

}
}
class FullScreenCodeDialogState : State<FullScreenCodeDialog> {
public class FullScreenCodeDialogState : State<FullScreenCodeDialog> {
public FullScreenCodeDialogState() {
}

base.didChangeDependencies();
string code = new ExampleCodeParser().getExampleCode(this.widget.exampleCodeTag, DefaultAssetBundle.of(this.context));
string code =
new ExampleCodeParser().getExampleCode(this.widget.exampleCodeTag, DefaultAssetBundle.of(this.context));
if (this.mounted) {
this.setState(() => { this._exampleCode = code; });
}

title: new Text("Example code")
),
body: body
);
}
}
class MaterialDemoDocumentationButton : StatelessWidget {
public MaterialDemoDocumentationButton(string routeName, Key key = null) : base(key: key) {
this.documentationUrl = DemoUtils.kDemoDocumentationUrl[routeName];
D.assert(DemoUtils.kDemoDocumentationUrl[routeName] != null,
"A documentation URL was not specified for demo route $routeName in kAllGalleryDemos"
);
}
public readonly string documentationUrl;
public override Widget build(BuildContext context) {
return new IconButton(
icon: new Icon(Icons.library_books),
tooltip: "API documentation",
onPressed: () => Application.OpenURL(this.documentationUrl)
);
}
}

18
Samples/UIWidgetsGallery/gallery/demos.cs


// documentationUrl: "https://docs.flutter.io/flutter/material/FloatingActionButton-class.html",
// buildRoute: (BuildContext context) => TabsFabDemo()
// ),
// new GalleryDemo(
// title: "Cards",
// subtitle: "Baseline cards with rounded corners",
// icon: GalleryIcons.cards,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: CardsDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/Card-class.html",
// buildRoute: (BuildContext context) => CardsDemo()
// ),
new GalleryDemo(
title: "Cards",
subtitle: "Baseline cards with rounded corners",
icon: GalleryIcons.cards,
category: DemoUtils._kMaterialComponents,
routeName: CardsDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/Card-class.html",
buildRoute: (BuildContext context) => new CardsDemo()
),
// new GalleryDemo(
// title: "Chips",
// subtitle: "Labeled with delete buttons and avatars",

217
Samples/UIWidgetsGallery/demo/material/cards_demo.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using Image = Unity.UIWidgets.widgets.Image;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsGallery.gallery {
class CardsDemoConstants {
public static readonly List<TravelDestination> destinations = new List<TravelDestination> {
new TravelDestination(
assetName: "india_thanjavur_market",
title: "Top 10 Cities to Visit in Tamil Nadu",
description: new List<string> {
"Number 10",
"Thanjavur",
"Thanjavur, Tamil Nadu"
}
),
new TravelDestination(
assetName: "india_chettinad_silk_maker",
title: "Artisans of Southern India",
description: new List<string> {
"Silk Spinners",
"Chettinad",
"Sivaganga, Tamil Nadu"
}
)
};
}
public class TravelDestination {
public TravelDestination(
string assetName = null,
string title = null,
List<string> description = null
) {
this.assetName = assetName;
this.title = title;
this.description = description;
}
public readonly string assetName;
public readonly string title;
public readonly List<string> description;
public bool isValid {
get { return this.assetName != null && this.title != null && this.description?.Count == 3; }
}
}
public class TravelDestinationItem : StatelessWidget {
public TravelDestinationItem(Key key = null, TravelDestination destination = null, ShapeBorder shape = null)
: base(key: key) {
D.assert(destination != null && destination.isValid);
this.destination = destination;
this.shape = shape;
}
public const float height = 366.0f;
public readonly TravelDestination destination;
public readonly ShapeBorder shape;
public override Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
TextStyle titleStyle = theme.textTheme.headline.copyWith(color: Colors.white);
TextStyle descriptionStyle = theme.textTheme.subhead;
return new SafeArea(
top: false,
bottom: false,
child: new Container(
padding: EdgeInsets.all(8.0f),
height: height,
child: new Card(
shape: this.shape,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget> {
new SizedBox(
height: 184.0f,
child: new Stack(
children: new List<Widget> {
Positioned.fill(
child: Image.asset(this.destination.assetName,
fit: BoxFit.cover
)
),
new Positioned(
bottom: 16.0f,
left: 16.0f,
right: 16.0f,
child: new FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: new Text(this.destination.title,
style: titleStyle
)
)
)
}
)
),
new Expanded(
child: new Padding(
padding: EdgeInsets.fromLTRB(16.0f, 16.0f, 16.0f, 0.0f),
child: new DefaultTextStyle(
softWrap: false,
overflow: TextOverflow.ellipsis,
style: descriptionStyle,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget> {
new Padding(
padding: EdgeInsets.only(bottom: 8.0f),
child: new Text(this.destination.description[0],
style: descriptionStyle.copyWith(color: Colors.black54)
)
),
new Text(this.destination.description[1]),
new Text(this.destination.description[2])
}
)
)
)
),
ButtonTheme.bar(
child: new ButtonBar(
alignment: MainAxisAlignment.start,
children: new List<Widget> {
new FlatButton(
child: new Text("SHARE"),
textColor: Colors.amber.shade500,
onPressed: () => {
/* do nothing */
}
),
new FlatButton(
child: new Text("EXPLORE"),
textColor: Colors.amber.shade500,
onPressed: () => {
/* do nothing */
}
)
}
)
),
}
)
)
)
);
}
}
public class CardsDemo : StatefulWidget {
public const string routeName = "/material/cards";
public override State createState() {
return new _CardsDemoState();
}
}
class _CardsDemoState : State<CardsDemo> {
ShapeBorder _shape;
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Travel stream"),
actions: new List<Widget> {
new MaterialDemoDocumentationButton(CardsDemo.routeName),
new IconButton(
icon: new Icon(
Icons.sentiment_very_satisfied
),
onPressed: () => {
this.setState(() => {
this._shape = this._shape != null
? null
: new RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0f),
topRight: Radius.circular(16.0f),
bottomLeft: Radius.circular(2.0f),
bottomRight: Radius.circular(2.0f)
)
);
});
}
)
}
),
body: new ListView(
itemExtent: TravelDestinationItem.height,
padding: EdgeInsets.only(top: 8.0f, left: 8.0f, right: 8.0f),
children: CardsDemoConstants.destinations.Select<TravelDestination, Widget>(
(TravelDestination destination) => {
return new Container(
margin: EdgeInsets.only(bottom: 8.0f),
child: new TravelDestinationItem(
destination: destination,
shape: this._shape
)
);
}).ToList()
)
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/cards_demo.cs.meta


fileFormatVersion: 2
guid: f199ea32d87544c892f57b8af0fcbb03
timeCreated: 1553136548

1001
Tests/Resources/india_chettinad_silk_maker.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/india_chettinad_silk_maker.png.meta


fileFormatVersion: 2
guid: 759295bbc368246a0877963ba053ed5d
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

1001
Tests/Resources/india_thanjavur_market.png
文件差异内容过多而无法显示
查看文件

88
Tests/Resources/india_thanjavur_market.png.meta


fileFormatVersion: 2
guid: 69711c649948f4cb1ad20b82f1926a29
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存