Commit b9e121a5 authored by Viktor Lidholt's avatar Viktor Lidholt

New version of Button demo (#3174)

parent 5b5c701d
...@@ -3,59 +3,116 @@ ...@@ -3,59 +3,116 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'tabs_fab_demo.dart'; import '../gallery/demo.dart';
import 'dialog_demo.dart';
import 'snack_bar_demo.dart';
const String _floatingText =
"A floating action button is a circular material button that lifts "
"and displays an ink reaction on press. It turns and fades in when "
"it changes.";
const String _raisedText = const String _raisedText =
"A raised button is typically a rectangular material button that lifts " "# Raised buttons\n"
"and displays ink reactions on press. Raised buttons add dimension to " "Raised buttons add dimension to mostly flat layouts. They emphasize"
"mostly flat layouts. They emphasize functions on busy or wide spaces."; "functions on busy or wide spaces.";
const String _raisedCode =
"""// Create a flat button
new RaisedButton(
child: new Text('BUTTON TITLE'),
onPressed: () {
// Perform some action
}
);
// Create a disabled button
// The button is disabled because there is no
// onPressed method specified
new RaisedButton(
child: new Text('BUTTON TITLE')
);""";
const String _flatText = const String _flatText =
"# Flat buttons\n"
"A flat button is made of ink that displays ink reactions on press " "A flat button is made of ink that displays ink reactions on press "
"but does not lift. Use flat buttons on toolbars, in dialogs and " "but does not lift. Use flat buttons on toolbars, in dialogs and "
"inline with padding"; "inline with padding";
const String _dropdownText = const String _flatCode =
"A dropdown button selects between multiple selections. The button " """// Create a flat button
"displays the current state and a down arrow."; new FlatButton(
child: new Text('BUTTON TITLE'),
class _ButtonDemo { onPressed: () {
_ButtonDemo({ this.title, this.text, this.builder }) { // Perform some action
assert(title != null);
assert(text != null);
assert(builder != null);
} }
);
final String title; // Create a disabled button
final String text; // The button is disabled because there is no
final WidgetBuilder builder; // onPressed method specified
new FlatButton(
child: new Text('BUTTON TITLE')
);""";
TabLabel get tabLabel => new TabLabel(text: title.toUpperCase()); const String _dropdownText =
"# Dropdown buttons\n"
"A dropdown button displays a menu that's used to select a value from a "
"small set of values. The button displays the current value and a down "
"arrow.";
// The TabBarSelection created below saves and restores _ButtonDemo objects const String _dropdownCode =
// to recover this demo's selected tab. To enable it to compare restored """// Member variable holding value
// _ButtonDemo objects with new ones, define hashCode and operator== . String dropdownValue
@override // Drop down button with string values
bool operator==(Object other) { new DropDownButton<String>(
if (other.runtimeType != runtimeType) value: dropdownValue,
return false; onChanged: (String newValue) {
_ButtonDemo typedOther = other; // null indicates the user didn't select a
return typedOther.title == title && typedOther.text == text; // new value
} setState(() {
if (newValue != null)
dropdownValue = newValue;
});
},
items: <String>['One', 'Two', 'Free', 'Four']
.map((String value) {
return new DropDownMenuItem<String>(
value: value,
child: new Text(value));
})
.toList()
)""";
@override const String _iconText =
int get hashCode => hashValues(title.hashCode, text.hashCode); "IconButtons are appropriate for toggle buttons that allow a single choice to be "
} "selected or deselected, such as adding or removing an item's star.";
const String _iconCode =
"""// Member variable holding toggle value
bool iconButtonToggle;
// Toggable icon button
new IconButton(
icon: Icons.thumb_up,
onPressed: () {
setState(() => iconButtonToggle = !iconButtonToggle);
},
color: iconButtonToggle ? Theme.of(context).primaryColor : null
)""";
const String _actionText =
"# Floating action buttons\n"
"Floating action buttons are used for a promoted action. They are "
"distinguished by a circled icon floating above the UI and have motion "
"behaviors that include morphing, launching, and a transferring anchor "
"point.";
const String _actionCode =
"""// Floating action button in Scaffold
new Scaffold(
appBar: new AppBar(
title: new Text('Demo')
),
floatingActionButton: new FloatingActionButton(
child: new Icon(icon: Icons.add)
)
);""";
class ButtonsDemo extends StatefulWidget { class ButtonsDemo extends StatefulWidget {
@override @override
...@@ -63,101 +120,93 @@ class ButtonsDemo extends StatefulWidget { ...@@ -63,101 +120,93 @@ class ButtonsDemo extends StatefulWidget {
} }
class _ButtonsDemoState extends State<ButtonsDemo> { class _ButtonsDemoState extends State<ButtonsDemo> {
List<_ButtonDemo> _demos;
@override @override
void initState() { Widget build(BuildContext context) {
super.initState(); List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
_demos = <_ButtonDemo>[ new ComponentDemoTabData(
new _ButtonDemo(title: 'FLOATING', text: _floatingText, builder: buildFloatingButton), tabName: 'RAISED',
new _ButtonDemo(title: 'RAISED', text: _raisedText, builder: buildRaisedButton), description: _raisedText,
new _ButtonDemo(title: 'FLAT', text: _flatText, builder: buildFlatButton), widget: buildRaisedButton(),
new _ButtonDemo(title: 'DROPDOWN', text: _dropdownText, builder: buildDropdownButton) exampleCode: _raisedCode
),
new ComponentDemoTabData(
tabName: 'FLAT',
description: _flatText,
widget: buildFlatButton(),
exampleCode: _flatCode
),
new ComponentDemoTabData(
tabName: 'DROPDOWN',
description: _dropdownText,
widget: buildDropdownButton(),
exampleCode:
_dropdownCode
),
new ComponentDemoTabData(
tabName: 'ICON',
description: _iconText,
widget: buildIconButton(),
exampleCode: _iconCode
),
new ComponentDemoTabData(
tabName: 'ACTION',
description: _actionText,
widget: buildActionButton(),
exampleCode: _actionCode
),
]; ];
}
Widget buildFloatingButton(BuildContext context) { return new TabbedComponentDemoScaffold(
return new SizedBox( title: 'Buttons',
height: 128.0, demos: demos
child: new Center(
child: new FloatingActionButton(
tooltip: 'Open FAB demos',
child: new Icon(icon: Icons.add),
onPressed: () {
Navigator.push(context, new MaterialPageRoute<Null>(
builder: (BuildContext context) => new TabsFabDemo()
));
}
)
)
); );
} }
Widget buildRaisedButton(BuildContext context) { Widget buildRaisedButton() {
return new Container( return new Align(
margin: const EdgeInsets.symmetric(vertical: 16.0), alignment: new FractionalOffset(0.5, 0.4),
child: new Column( child: new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[ children: <Widget>[
new RaisedButton( new RaisedButton(
child: new Text('LAUNCH DEMO'), child: new Text('RAISED BUTTON'),
onPressed: () { onPressed: () {
Navigator.push(context, new MaterialPageRoute<Null>( // Perform some action
builder: (BuildContext context) => new SnackBarDemo()
));
} }
), ),
new RaisedButton( new RaisedButton(
child: new Text('DISABLED') child: new Text('DISABLED')
) )
] ]
.map((Widget child) {
return new Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: child
);
})
.toList()
) )
); );
} }
Widget buildFlatButton(BuildContext context) { Widget buildFlatButton() {
return new Container( return new Align(
margin: const EdgeInsets.symmetric(vertical: 16.0), alignment: new FractionalOffset(0.5, 0.4),
child: new ButtonTheme( child: new Row(
color: ButtonColor.accent, mainAxisAlignment: MainAxisAlignment.collapse,
child: new Column(
children: <Widget>[ children: <Widget>[
new FlatButton( new FlatButton(
child: new Text('LAUNCH DEMO'), child: new Text('FLAT BUTTON'),
onPressed: () { onPressed: () {
Navigator.push(context, new MaterialPageRoute<Null>( // Perform some action
builder: (_) => new DialogDemo()
));
} }
), ),
new FlatButton( new FlatButton(
child: new Text('DISABLED') child: new Text('DISABLED')
) )
] ]
.map((Widget child) {
return new Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: child
);
})
.toList()
)
) )
); );
} }
String dropdownValue = "Free"; String dropdownValue = 'Free';
Widget buildDropdownButton(BuildContext context) { Widget buildDropdownButton() {
return new SizedBox( return new Align(
height: 256.0, alignment: new FractionalOffset(0.5, 0.4),
child: new Center(
child: new DropDownButton<String>( child: new DropDownButton<String>(
value: dropdownValue, value: dropdownValue,
onChanged: (String newValue) { onChanged: (String newValue) {
...@@ -166,7 +215,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> { ...@@ -166,7 +215,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
dropdownValue = newValue; dropdownValue = newValue;
}); });
}, },
items: <String>["One", "Two", "Free", "Four"] items: <String>['One', 'Two', 'Free', 'Four']
.map((String value) { .map((String value) {
return new DropDownMenuItem<String>( return new DropDownMenuItem<String>(
value: value, value: value,
...@@ -174,42 +223,40 @@ class _ButtonsDemoState extends State<ButtonsDemo> { ...@@ -174,42 +223,40 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
}) })
.toList() .toList()
) )
)
); );
} }
Widget buildTabView(_ButtonDemo demo) { bool iconButtonToggle = false;
return new Builder(
builder: (BuildContext context) { Widget buildIconButton() {
final TextStyle textStyle = Theme.of(context).textTheme.caption.copyWith(fontSize: 16.0); return new Align(
return new Block( alignment: new FractionalOffset(0.5, 0.4),
child: new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[ children: <Widget>[
demo.builder(context), new IconButton(
new Padding( icon: Icons.thumb_up,
padding: const EdgeInsets.fromLTRB(32.0, 0.0, 32.0, 24.0), onPressed: () {
child: new Text(demo.text, style: textStyle) setState(() => iconButtonToggle = !iconButtonToggle);
},
color: iconButtonToggle ? Theme.of(context).primaryColor : null
),
new IconButton(
icon: Icons.thumb_up
) )
] ]
); )
}
); );
} }
@override Widget buildActionButton() {
Widget build(BuildContext context) { return new Align(
return new TabBarSelection<_ButtonDemo>( alignment: new FractionalOffset(0.5, 0.4),
values: _demos, child: new FloatingActionButton(
child: new Scaffold( child: new Icon(icon: Icons.add),
appBar: new AppBar( onPressed: () {
title: new Text('Buttons'), // Perform some action
tabBar: new TabBar<_ButtonDemo>( }
isScrollable: true,
labels: new Map<_ButtonDemo, TabLabel>.fromIterable(_demos, value: (_ButtonDemo demo) => demo.tabLabel)
)
),
body: new TabBarView<_ButtonDemo>(
children: _demos.map(buildTabView).toList()
)
) )
); );
} }
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// 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';
import 'package:flutter_markdown/flutter_markdown.dart';
import '../gallery/syntax_highlighter.dart';
class SingleComponentDemoData {
SingleComponentDemoData({
this.widget,
this.exampleCode,
this.description,
this.onPressedDemo
});
final Widget widget;
final String exampleCode;
final String description;
final VoidCallback onPressedDemo;
}
class ComponentDemoTabData extends SingleComponentDemoData {
ComponentDemoTabData({
Widget widget,
String exampleCode,
String description,
VoidCallback onPressedDemo,
this.tabName
}) : super(
widget: widget,
exampleCode: exampleCode,
description: description,
onPressedDemo: onPressedDemo
);
final String tabName;
static Map<ComponentDemoTabData, TabLabel> buildTabLabels(List<ComponentDemoTabData> demos) {
return new Map<ComponentDemoTabData, TabLabel>.fromIterable(
demos,
value: (ComponentDemoTabData demo) => new TabLabel(text: demo.tabName)
);
}
@override
bool operator==(Object other) {
if (other.runtimeType != runtimeType)
return false;
ComponentDemoTabData typedOther = other;
return typedOther.tabName == tabName && typedOther.description == description;
}
@override
int get hashCode => hashValues(tabName.hashCode, description.hashCode);
}
class TabbedComponentDemoScaffold extends StatelessWidget {
TabbedComponentDemoScaffold({
this.title,
this.demos
});
final List<ComponentDemoTabData> demos;
final String title;
@override
Widget build(BuildContext context) {
return new TabBarSelection<ComponentDemoTabData>(
values: demos,
child: new Scaffold(
appBar: new AppBar(
title: new Text(title),
tabBar: new TabBar<ComponentDemoTabData>(
isScrollable: true,
labels: ComponentDemoTabData.buildTabLabels(demos)
)
),
body: new TabbedComponentDemo(demos)
)
);
}
}
class TabbedComponentDemo extends StatelessWidget {
TabbedComponentDemo(this.demos);
final List<ComponentDemoTabData> demos;
@override
Widget build(BuildContext context) {
return new TabBarView<ComponentDemoTabData>(
children: demos.map(buildTabView).toList()
);
}
Widget buildTabView(ComponentDemoTabData demo) {
return new SingleComponentDemo(demo);
}
}
class SingleComponentDemo extends StatelessWidget {
SingleComponentDemo(this.demo);
final SingleComponentDemoData demo;
@override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new Padding(
padding: new EdgeInsets.all(16.0),
child: new MarkdownBody(data: demo.description)
),
new Flexible(
child: demo.widget
),
new DemoBottomBar(
exampleCode: demo.exampleCode,
onPressedDemo: demo.onPressedDemo
)
]
);
}
}
class DemoBottomBar extends StatelessWidget {
DemoBottomBar({ this.exampleCode, this.onPressedDemo });
final String exampleCode;
final VoidCallback onPressedDemo;
@override
Widget build(BuildContext context) {
VoidCallback onPressedCode;
if (exampleCode != null) {
onPressedCode = () {
Navigator.push(context, new MaterialPageRoute<FullScreenCodeDialog>(
builder: (BuildContext context) => new FullScreenCodeDialog(code: exampleCode)
));
};
}
return new Column(
children: <Widget>[
new Divider(
height: 1.0
),
new Container(
height: 48.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new FlatButton(
child: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(right: 8.0),
child: new Icon(icon: Icons.code)
),
new Text('VIEW CODE')
]
),
onPressed: onPressedCode
),
new FlatButton(
child: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(right: 8.0),
child: new Icon(icon: Icons.star)
),
new Text('LIVE DEMO')
]
),
onPressed: onPressedDemo
)
]
)
)
]
);
}
}
class FormattedCode extends StatefulWidget {
FormattedCode(this.code);
final String code;
@override
_FormattedCodeState createState() => new _FormattedCodeState();
}
class _FormattedCodeState extends State<FormattedCode> {
@override
void initState() {
super.initState();
_formatText();
}
TextSpan _formattedText;
@override
Widget build(BuildContext context) {
return new RichText(text: _formattedText);
}
@override
void didUpdateConfig(FormattedCode oldConfig) {
super.didUpdateConfig(oldConfig);
if (oldConfig.code != config.code)
_formatText();
}
void _formatText() {
_formattedText = new TextSpan(
style: new TextStyle(fontFamily: 'monospace', fontSize: 10.0),
children: <TextSpan>[new DartSyntaxHighlighter().format(config.code)]
);
}
}
class FullScreenCodeDialog extends StatelessWidget {
FullScreenCodeDialog({ this.code });
final String code;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
leading: new IconButton(
icon: Icons.clear,
onPressed: () { Navigator.pop(context); }
),
title: new Text('Example Code')
),
body: new ScrollableViewport(
child: new Padding(
padding: new EdgeInsets.all(16.0),
child: new FormattedCode(code)
)
)
);
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// 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';
import 'package:string_scanner/string_scanner.dart';
class SyntaxHighlighterStyle {
SyntaxHighlighterStyle({
this.baseStyle,
this.numberStyle,
this.commentStyle,
this.keywordStyle,
this.stringStyle,
this.punctuationStyle,
this.classStyle,
this.constantStyle
});
static SyntaxHighlighterStyle defaultStyle() {
return new SyntaxHighlighterStyle(
baseStyle: new TextStyle(color: const Color(0xff000000)),
numberStyle: new TextStyle(color: const Color(0xFF1565C0)),
commentStyle: new TextStyle(color: const Color(0xFF9E9E9E)),
keywordStyle: new TextStyle(color: const Color(0xFF9C27B0)),
stringStyle: new TextStyle(color: const Color(0xFF43A047)),
punctuationStyle: new TextStyle(color: const Color(0xff000000)),
classStyle: new TextStyle(color: const Color(0xFF512DA8)),
constantStyle: new TextStyle(color: const Color(0xFF795548))
);
}
final TextStyle baseStyle;
final TextStyle numberStyle;
final TextStyle commentStyle;
final TextStyle keywordStyle;
final TextStyle stringStyle;
final TextStyle punctuationStyle;
final TextStyle classStyle;
final TextStyle constantStyle;
}
abstract class SyntaxHighlighter {
TextSpan format(String src);
}
class DartSyntaxHighlighter extends SyntaxHighlighter {
DartSyntaxHighlighter([this._style]) {
_spans = <_HighlightSpan>[];
if (_style == null)
_style = SyntaxHighlighterStyle.defaultStyle();
}
SyntaxHighlighterStyle _style;
static const List<String> _kKeywords = const <String>[
'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch',
'class', 'const', 'continue', 'default', 'deferred', 'do', 'dynamic', 'else',
'enum', 'export', 'external', 'extends', 'factory', 'false', 'final',
'finally', 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library',
'new', 'null', 'operator', 'part', 'rethrow', 'return', 'set', 'static',
'super', 'switch', 'sync', 'this', 'throw', 'true', 'try', 'typedef', 'var',
'void', 'while', 'with', 'yield'
];
static const List<String> _kBuiltInTypes = const <String>[
'int', 'double', 'num', 'bool'
];
String _src;
StringScanner _scanner;
List<_HighlightSpan> _spans;
@override
TextSpan format(String src) {
_src = src;
_scanner = new StringScanner(_src);
if (_generateSpans()) {
// Successfully parsed the code
List<TextSpan> formattedText = <TextSpan>[];
int currentPosition = 0;
for (_HighlightSpan span in _spans) {
if (currentPosition != span.start)
formattedText.add(new TextSpan(text: _src.substring(currentPosition, span.start)));
formattedText.add(new TextSpan(style: span.textStyle(_style), text: span.textForSpan(_src)));
currentPosition = span.end;
}
if (currentPosition != _src.length)
formattedText.add(new TextSpan(text: _src.substring(currentPosition, _src.length)));
return new TextSpan(style: _style.baseStyle, children: formattedText);
} else {
// Parsing failed, return with only basic formatting
return new TextSpan(style:_style.baseStyle, text: src);
}
}
bool _generateSpans() {
int lastLoopPosition = _scanner.position;
while(!_scanner.isDone) {
// Skip White space
_scanner.scan(new RegExp(r"\s+"));
// Block comments
if (_scanner.scan(new RegExp(r"/\*(.|\n)*\*/"))) {
_spans.add(new _HighlightSpan(
_HighlightType.comment,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Line comments
if (_scanner.scan("//")) {
int startComment = _scanner.lastMatch.start;
bool eof = false;
int endComment;
if (_scanner.scan(new RegExp(r".*\n"))) {
endComment = _scanner.lastMatch.end - 1;
} else {
eof = true;
endComment = _src.length;
}
_spans.add(new _HighlightSpan(
_HighlightType.comment,
startComment,
endComment
));
if (eof)
break;
continue;
}
// Raw r"String"
if (_scanner.scan(new RegExp(r'r".*"'))) {
_spans.add(new _HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Raw r'String'
if (_scanner.scan(new RegExp(r"r'.*'"))) {
_spans.add(new _HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline """String"""
if (_scanner.scan(new RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
_spans.add(new _HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline '''String'''
if (_scanner.scan(new RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
_spans.add(new _HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// "String"
if (_scanner.scan(new RegExp(r'"(?:[^"\\]|\\.)*"'))) {
_spans.add(new _HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// 'String'
if (_scanner.scan(new RegExp(r"'(?:[^'\\]|\\.)*'"))) {
_spans.add(new _HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Double
if (_scanner.scan(new RegExp(r"\d+\.\d+"))) {
_spans.add(new _HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Integer
if (_scanner.scan(new RegExp(r"\d+"))) {
_spans.add(new _HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end)
);
continue;
}
// Punctuation
if (_scanner.scan(new RegExp(r"[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]"))) {
_spans.add(new _HighlightSpan(
_HighlightType.punctuation,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Metadata
if (_scanner.scan(new RegExp(r"@\w+"))) {
_spans.add(new _HighlightSpan(
_HighlightType.keyword,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Words
if (_scanner.scan(new RegExp(r"\w+"))) {
_HighlightType type;
String word = _scanner.lastMatch[0];
if (word.startsWith("_"))
word = word.substring(1);
if (_kKeywords.contains(word))
type = _HighlightType.keyword;
else if (_kBuiltInTypes.contains(word))
type = _HighlightType.keyword;
else if (_firstLetterIsUpperCase(word))
type = _HighlightType.klass;
else if (word.length >= 2 && word.startsWith("k") && _firstLetterIsUpperCase(word.substring(1)))
type = _HighlightType.constant;
if (type != null) {
_spans.add(new _HighlightSpan(
type,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
}
}
// Check if this loop did anything
if (lastLoopPosition == _scanner.position) {
// Failed to parse this file, abort gracefully
return false;
}
lastLoopPosition = _scanner.position;
}
_simplify();
return true;
}
void _simplify() {
for(int i = _spans.length - 2; i >= 0; i -= 1) {
if (_spans[i].type == _spans[i + 1].type && _spans[i].end == _spans[i + 1].start) {
_spans[i] = new _HighlightSpan(
_spans[i].type,
_spans[i].start,
_spans[i + 1].end
);
_spans.removeAt(i + 1);
}
}
}
bool _firstLetterIsUpperCase(String str) {
if (str.length > 0) {
String first = str.substring(0, 1);
return first == first.toUpperCase();
}
return false;
}
}
enum _HighlightType {
number,
comment,
keyword,
string,
punctuation,
klass,
constant
}
class _HighlightSpan {
_HighlightSpan(this.type, this.start, this.end);
final _HighlightType type;
final int start;
final int end;
String textForSpan(String src) {
return src.substring(start, end);
}
TextStyle textStyle(SyntaxHighlighterStyle style) {
if (type == _HighlightType.number)
return style.numberStyle;
else if (type == _HighlightType.comment)
return style.commentStyle;
else if (type == _HighlightType.keyword)
return style.keywordStyle;
else if (type == _HighlightType.string)
return style.stringStyle;
else if (type == _HighlightType.punctuation)
return style.punctuationStyle;
else if (type == _HighlightType.klass)
return style.classStyle;
else if (type == _HighlightType.constant)
return style.constantStyle;
else
return style.baseStyle;
}
}
...@@ -2,9 +2,12 @@ name: material_gallery ...@@ -2,9 +2,12 @@ name: material_gallery
dependencies: dependencies:
intl: '>=0.12.4+2 <0.13.0' intl: '>=0.12.4+2 <0.13.0'
collection: '>=1.4.0 <2.0.0' collection: '>=1.4.0 <2.0.0'
string_scanner: '0.1.4+1'
flutter: flutter:
path: ../../packages/flutter path: ../../packages/flutter
flutter_sprites: flutter_sprites:
path: ../../packages/flutter_sprites path: ../../packages/flutter_sprites
flutter_markdown:
path: ../../packages/flutter_markdown
flutter_gallery_assets: '0.0.13' flutter_gallery_assets: '0.0.13'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment