-
Notifications
You must be signed in to change notification settings - Fork 551
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from memspace/toolbar-overlay
Allow embedding Zefyr into custom layouts with ZefyrScaffold
- Loading branch information
Showing
23 changed files
with
566 additions
and
207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,3 +14,5 @@ example/ios/.symlinks | |
example/ios/Flutter/Generated.xcconfig | ||
doc/api/ | ||
build/ | ||
|
||
example/feather |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,125 +1,67 @@ | ||
// Copyright (c) 2018, the Zefyr project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
import 'dart:convert'; | ||
|
||
import 'package:flutter/material.dart'; | ||
import 'package:quill_delta/quill_delta.dart'; | ||
import 'package:zefyr/zefyr.dart'; | ||
import 'src/form.dart'; | ||
import 'src/full_page.dart'; | ||
|
||
void main() { | ||
runApp(new ZefyrApp()); | ||
} | ||
|
||
class ZefyrLogo extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
return Row( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: <Widget>[ | ||
Text('Ze'), | ||
FlutterLogo(size: 24.0), | ||
Text('yr'), | ||
], | ||
); | ||
} | ||
} | ||
|
||
class ZefyrApp extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
return new MaterialApp( | ||
return MaterialApp( | ||
debugShowCheckedModeBanner: false, | ||
title: 'Zefyr Editor', | ||
theme: new ThemeData(primarySwatch: Colors.cyan), | ||
home: new MyHomePage(), | ||
theme: ThemeData(primarySwatch: Colors.cyan), | ||
home: HomePage(), | ||
routes: { | ||
"/fullPage": buildFullPage, | ||
"/form": buildFormPage, | ||
}, | ||
); | ||
} | ||
} | ||
|
||
class MyHomePage extends StatefulWidget { | ||
@override | ||
_MyHomePageState createState() => new _MyHomePageState(); | ||
} | ||
|
||
final doc = | ||
r'[{"insert":"Zefyr"},{"insert":"\n","attributes":{"heading":1}},{"insert":"Soft and gentle rich text editing for Flutter applications.","attributes":{"i":true}},{"insert":"\n"},{"insert":"","attributes":{"embed":{"type":"image","source":"asset://images/breeze.jpg"}}},{"insert":"\n"},{"insert":"Photo by Hiroyuki Takeda.","attributes":{"i":true}},{"insert":"\nZefyr is currently in "},{"insert":"early preview","attributes":{"b":true}},{"insert":". If you have a feature request or found a bug, please file it at the "},{"insert":"issue tracker","attributes":{"a":"https://github.com/memspace/zefyr/issues"}},{"insert":' | ||
r'".\nDocumentation"},{"insert":"\n","attributes":{"heading":3}},{"insert":"Quick Start","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/quick_start.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Data Format and Document Model","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/data_and_document.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Style Attributes","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/attr' | ||
r'ibutes.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Heuristic Rules","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/heuristics.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"FAQ","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/faq.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Clean and modern look"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Zefyr’s rich text editor is built with simplicity and fle' | ||
r'xibility in mind. It provides clean interface for distraction-free editing. Think Medium.com-like experience.\nMarkdown inspired semantics"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Ever needed to have a heading line inside of a quote block, like this:\nI’m a Markdown heading"},{"insert":"\n","attributes":{"block":"quote","heading":3}},{"insert":"And I’m a regular paragraph"},{"insert":"\n","attributes":{"block":"quote"}},{"insert":"Code blocks"},{"insert":"\n","attributes":{"headin' | ||
r'g":2}},{"insert":"Of course:\nimport ‘package:flutter/material.dart’;"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"import ‘package:zefyr/zefyr.dart’;"},{"insert":"\n\n","attributes":{"block":"code"}},{"insert":"void main() {"},{"insert":"\n","attributes":{"block":"code"}},{"insert":" runApp(MyZefyrApp());"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"}"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"\n\n\n"}]'; | ||
Widget buildFullPage(BuildContext context) { | ||
return FullPageEditorScreen(); | ||
} | ||
|
||
Delta getDelta() { | ||
return Delta.fromJson(json.decode(doc)); | ||
Widget buildFormPage(BuildContext context) { | ||
return FormEmbeddedScreen(); | ||
} | ||
} | ||
|
||
class _MyHomePageState extends State<MyHomePage> { | ||
final ZefyrController _controller = | ||
ZefyrController(NotusDocument.fromDelta(getDelta())); | ||
final FocusNode _focusNode = new FocusNode(); | ||
bool _editing = false; | ||
|
||
class HomePage extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
final theme = new ZefyrThemeData( | ||
toolbarTheme: ZefyrToolbarTheme.fallback(context).copyWith( | ||
color: Colors.grey.shade800, | ||
toggleColor: Colors.grey.shade900, | ||
iconColor: Colors.white, | ||
disabledIconColor: Colors.grey.shade500, | ||
), | ||
); | ||
|
||
final done = _editing | ||
? [new FlatButton(onPressed: _stopEditing, child: Text('DONE'))] | ||
: [new FlatButton(onPressed: _startEditing, child: Text('EDIT'))]; | ||
final nav = Navigator.of(context); | ||
return Scaffold( | ||
resizeToAvoidBottomPadding: true, | ||
appBar: AppBar( | ||
elevation: 1.0, | ||
backgroundColor: Colors.grey.shade200, | ||
brightness: Brightness.light, | ||
title: ZefyrLogo(), | ||
actions: done, | ||
), | ||
body: ZefyrTheme( | ||
data: theme, | ||
child: ZefyrEditor( | ||
controller: _controller, | ||
focusNode: _focusNode, | ||
enabled: _editing, | ||
imageDelegate: new CustomImageDelegate(), | ||
), | ||
body: Column( | ||
children: <Widget>[ | ||
Expanded(child: Container()), | ||
FlatButton( | ||
onPressed: () => nav.pushNamed('/fullPage'), | ||
child: Text('Full page editor'), | ||
color: Colors.lightBlue, | ||
textColor: Colors.white, | ||
), | ||
FlatButton( | ||
onPressed: () => nav.pushNamed('/form'), | ||
child: Text('Embedded in a form'), | ||
color: Colors.lightBlue, | ||
textColor: Colors.white, | ||
), | ||
Expanded(child: Container()), | ||
], | ||
), | ||
); | ||
} | ||
|
||
void _startEditing() { | ||
setState(() { | ||
_editing = true; | ||
}); | ||
} | ||
|
||
void _stopEditing() { | ||
setState(() { | ||
_editing = false; | ||
}); | ||
} | ||
} | ||
|
||
/// Custom image delegate used by this example to load image from application | ||
/// assets. | ||
/// | ||
/// Default image delegate only supports [FileImage]s. | ||
class CustomImageDelegate extends ZefyrDefaultImageDelegate { | ||
@override | ||
Widget buildImage(BuildContext context, String imageSource) { | ||
// We use custom "asset" scheme to distinguish asset images from other files. | ||
if (imageSource.startsWith('asset://')) { | ||
final asset = new AssetImage(imageSource.replaceFirst('asset://', '')); | ||
return new Image(image: asset); | ||
} else { | ||
return super.buildImage(context, imageSource); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:zefyr/zefyr.dart'; | ||
|
||
import 'full_page.dart'; | ||
|
||
class FormEmbeddedScreen extends StatefulWidget { | ||
@override | ||
_FormEmbeddedScreenState createState() => _FormEmbeddedScreenState(); | ||
} | ||
|
||
class _FormEmbeddedScreenState extends State<FormEmbeddedScreen> { | ||
final ZefyrController _controller = ZefyrController(NotusDocument()); | ||
final FocusNode _focusNode = new FocusNode(); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final form = ListView( | ||
children: <Widget>[ | ||
TextField(decoration: InputDecoration(labelText: 'Name')), | ||
buildEditor(), | ||
TextField(decoration: InputDecoration(labelText: 'Email')), | ||
], | ||
); | ||
|
||
return Scaffold( | ||
resizeToAvoidBottomPadding: true, | ||
appBar: AppBar( | ||
elevation: 1.0, | ||
backgroundColor: Colors.grey.shade200, | ||
brightness: Brightness.light, | ||
title: ZefyrLogo(), | ||
), | ||
body: ZefyrScaffold( | ||
child: Padding( | ||
padding: const EdgeInsets.all(8.0), | ||
child: form, | ||
), | ||
), | ||
); | ||
} | ||
|
||
Widget buildEditor() { | ||
final theme = new ZefyrThemeData( | ||
toolbarTheme: ZefyrToolbarTheme.fallback(context).copyWith( | ||
color: Colors.grey.shade800, | ||
toggleColor: Colors.grey.shade900, | ||
iconColor: Colors.white, | ||
disabledIconColor: Colors.grey.shade500, | ||
), | ||
); | ||
|
||
return ZefyrTheme( | ||
data: theme, | ||
child: ZefyrField( | ||
height: 200.0, | ||
decoration: InputDecoration(labelText: 'Description'), | ||
controller: _controller, | ||
focusNode: _focusNode, | ||
autofocus: false, | ||
imageDelegate: new CustomImageDelegate(), | ||
physics: ClampingScrollPhysics(), | ||
), | ||
); | ||
} | ||
} |
Oops, something went wrong.