feat: added font size dialog and icon tooltip

This commit is contained in:
jideguru 2021-05-29 18:02:50 +01:00
parent 25c6c39e1b
commit 758a107ed3
7 changed files with 144 additions and 71 deletions

View File

@ -1,23 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Spoon-Knife</title>
<LINK href="styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<img src="forkit.gif" id="octocat" alt="" />
<!-- Feel free to change this text here -->
<p>
Fork me? Fork you, @octocat!
</p>
<p>
Sean made a change
</p>
</body>
</html>

View File

@ -1,3 +1,5 @@
library rich_editor; library rich_editor;
export 'package:rich_editor/src/rendering/rich_editor.dart'; export 'src/rendering/rich_editor.dart';
export 'src/widgets/tabs.dart';
export 'src/widgets/tab_button.dart';

View File

@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
class FontSizeDialog extends StatelessWidget {
List formats = [
{'id': '1', 'title': '<small><small><small>Teeny</small></small></small>'},
{'id': '2', 'title': '<small><small>Very small</small></small>'},
{'id': '3', 'title': '<small>Small</small>'},
{'id': '4', 'title': 'Medium'},
{'id': '5', 'title': '<big>Large</big>'},
{'id': '6', 'title': '<big><big>Very large</big></big>'},
{'id': '7', 'title': '<big><big><big>Huge</big></big></big>'},
];
@override
Widget build(BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
for (Map format in formats)
InkWell(
child: Html(data: format['title']),
onTap: () => Navigator.pop(context, format['id']),
)
],
),
),
);
}
}

View File

@ -15,7 +15,9 @@ class FontsDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return AlertDialog(
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -25,6 +27,8 @@ class FontsDialog extends StatelessWidget {
onTap: () => Navigator.pop(context, font['id']), onTap: () => Navigator.pop(context, font['id']),
) )
], ],
),
),
); );
} }
} }

View File

@ -19,7 +19,9 @@ class HeadingDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return AlertDialog(
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -29,6 +31,8 @@ class HeadingDialog extends StatelessWidget {
onTap: () => Navigator.pop(context, format['id']), onTap: () => Navigator.pop(context, format['id']),
) )
], ],
),
),
); );
} }
} }

View File

@ -3,13 +3,16 @@ import 'package:flutter/material.dart';
class TabButton extends StatelessWidget { class TabButton extends StatelessWidget {
final IconData? icon; final IconData? icon;
final Function? onTap; final Function? onTap;
final String tooltip;
TabButton({this.icon, this.onTap}); TabButton({this.icon, this.onTap, this.tooltip = ''});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0), padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
child: Tooltip(
message: '$tooltip',
child: Container( child: Container(
height: 45.0, height: 45.0,
width: 45.0, width: 45.0,
@ -36,6 +39,7 @@ class TabButton extends StatelessWidget {
), ),
), ),
), ),
),
); );
} }
} }

View File

@ -8,6 +8,7 @@ import 'package:rich_editor/src/widgets/tab_button.dart';
import 'package:webview_flutter/webview_flutter.dart'; import 'package:webview_flutter/webview_flutter.dart';
import 'color_picker_dialog.dart'; import 'color_picker_dialog.dart';
import 'font_size_dialog.dart';
import 'heading_dialog.dart'; import 'heading_dialog.dart';
class GroupedTab extends StatelessWidget { class GroupedTab extends StatelessWidget {
@ -34,20 +35,24 @@ class GroupedTab extends StatelessWidget {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
children: [ children: [
TabButton( TabButton(
tooltip: 'Bold',
icon: Icons.format_bold, icon: Icons.format_bold,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setBold(); await javascriptExecutorBase.setBold();
}, },
), ),
TabButton( TabButton(
tooltip: 'Italic',
icon: Icons.format_italic, icon: Icons.format_italic,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setItalic(); await javascriptExecutorBase.setItalic();
}, },
), ),
TabButton( TabButton(
tooltip: 'Insert Link',
icon: Icons.link, icon: Icons.link,
onTap: () async { onTap: () async {
_closeKeyboard();
var link = await showDialog( var link = await showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@ -60,8 +65,10 @@ class GroupedTab extends StatelessWidget {
}, },
), ),
TabButton( TabButton(
tooltip: 'Insert Image',
icon: Icons.image, icon: Icons.image,
onTap: () async { onTap: () async {
_closeKeyboard();
var link = await showDialog( var link = await showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@ -78,59 +85,68 @@ class GroupedTab extends StatelessWidget {
}, },
), ),
TabButton( TabButton(
tooltip: 'Underline',
icon: Icons.format_underline, icon: Icons.format_underline,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setUnderline(); await javascriptExecutorBase.setUnderline();
}, },
), ),
TabButton( TabButton(
tooltip: 'Strike through',
icon: Icons.format_strikethrough, icon: Icons.format_strikethrough,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setStrikeThrough(); await javascriptExecutorBase.setStrikeThrough();
}, },
), ),
TabButton( TabButton(
tooltip: 'Superscript',
icon: Icons.superscript, icon: Icons.superscript,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setSuperscript(); await javascriptExecutorBase.setSuperscript();
}, },
), ),
TabButton( TabButton(
tooltip: 'Subscript',
icon: Icons.subscript, icon: Icons.subscript,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setSubscript(); await javascriptExecutorBase.setSubscript();
}, },
), ),
TabButton( TabButton(
tooltip: 'Clear format',
icon: Icons.format_clear, icon: Icons.format_clear,
onTap: () async { onTap: () async {
await javascriptExecutorBase.removeFormat(); await javascriptExecutorBase.removeFormat();
}, },
), ),
TabButton( TabButton(
tooltip: 'Undo',
icon: Icons.undo, icon: Icons.undo,
onTap: () async { onTap: () async {
await javascriptExecutorBase.undo(); await javascriptExecutorBase.undo();
}, },
), ),
TabButton( TabButton(
tooltip: 'Redo',
icon: Icons.redo, icon: Icons.redo,
onTap: () async { onTap: () async {
await javascriptExecutorBase.redo(); await javascriptExecutorBase.redo();
}, },
), ),
TabButton( TabButton(
tooltip: 'Blockquote',
icon: Icons.format_quote, icon: Icons.format_quote,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setBlockQuote(); await javascriptExecutorBase.setBlockQuote();
}, },
), ),
TabButton( TabButton(
tooltip: 'Font format',
icon: Icons.text_format, icon: Icons.text_format,
onTap: () async { onTap: () async {
var command = await showModalBottomSheet( _closeKeyboard();
isScrollControlled: true, var command = await showDialog(
// isScrollControlled: true,
context: context, context: context,
builder: (_) { builder: (_) {
return HeadingDialog(); return HeadingDialog();
@ -151,10 +167,12 @@ class GroupedTab extends StatelessWidget {
}, },
), ),
TabButton( TabButton(
tooltip: 'Font face',
icon: Icons.font_download, icon: Icons.font_download,
onTap: () async { onTap: () async {
var command = await showModalBottomSheet( _closeKeyboard();
isScrollControlled: true, var command = await showDialog(
// isScrollControlled: true,
context: context, context: context,
builder: (_) { builder: (_) {
return FontsDialog(); return FontsDialog();
@ -166,13 +184,25 @@ class GroupedTab extends StatelessWidget {
), ),
TabButton( TabButton(
icon: Icons.format_size, icon: Icons.format_size,
tooltip: 'Font Size',
onTap: () async { onTap: () async {
await javascriptExecutorBase.setFontSize(7); _closeKeyboard();
String? command = await showDialog(
// isScrollControlled: true,
context: context,
builder: (_) {
return FontSizeDialog();
},
);
if (command != null)
await javascriptExecutorBase.setFontSize(int.tryParse(command)!);
}, },
), ),
TabButton( TabButton(
tooltip: 'Text Color',
icon: Icons.format_color_text, icon: Icons.format_color_text,
onTap: () async { onTap: () async {
_closeKeyboard();
var color = await showDialog( var color = await showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
@ -184,8 +214,10 @@ class GroupedTab extends StatelessWidget {
}, },
), ),
TabButton( TabButton(
tooltip: 'Background Color',
icon: Icons.format_color_fill, icon: Icons.format_color_fill,
onTap: () async { onTap: () async {
_closeKeyboard();
var color = await showDialog( var color = await showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
@ -198,56 +230,66 @@ class GroupedTab extends StatelessWidget {
}, },
), ),
TabButton( TabButton(
tooltip: 'Increase Indent',
icon: Icons.format_indent_increase, icon: Icons.format_indent_increase,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setIndent(); await javascriptExecutorBase.setIndent();
}, },
), ),
TabButton( TabButton(
tooltip: 'Decrease Indent',
icon: Icons.format_indent_decrease, icon: Icons.format_indent_decrease,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setOutdent(); await javascriptExecutorBase.setOutdent();
}, },
), ),
TabButton( TabButton(
tooltip: 'Align Left',
icon: Icons.format_align_left_outlined, icon: Icons.format_align_left_outlined,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setJustifyLeft(); await javascriptExecutorBase.setJustifyLeft();
}, },
), ),
TabButton( TabButton(
tooltip: 'Align Center',
icon: Icons.format_align_center, icon: Icons.format_align_center,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setJustifyCenter(); await javascriptExecutorBase.setJustifyCenter();
}, },
), ),
TabButton( TabButton(
tooltip: 'Align Right',
icon: Icons.format_align_right, icon: Icons.format_align_right,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setJustifyRight(); await javascriptExecutorBase.setJustifyRight();
}, },
), ),
TabButton( TabButton(
tooltip: 'Justify',
icon: Icons.format_align_justify, icon: Icons.format_align_justify,
onTap: () async { onTap: () async {
await javascriptExecutorBase.setJustifyFull(); await javascriptExecutorBase.setJustifyFull();
}, },
), ),
TabButton( TabButton(
tooltip: 'Bullet List',
icon: Icons.format_list_bulleted, icon: Icons.format_list_bulleted,
onTap: () async { onTap: () async {
await javascriptExecutorBase.insertBulletList(); await javascriptExecutorBase.insertBulletList();
}, },
), ),
TabButton( TabButton(
tooltip: 'Numbered List',
icon: Icons.format_list_numbered, icon: Icons.format_list_numbered,
onTap: () async { onTap: () async {
await javascriptExecutorBase.insertNumberedList(); await javascriptExecutorBase.insertNumberedList();
}, },
), ),
TabButton( TabButton(
tooltip: 'Checkbox',
icon: Icons.check_box_outlined, icon: Icons.check_box_outlined,
onTap: () async { onTap: () async {
_closeKeyboard();
var text = await showDialog( var text = await showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
@ -255,11 +297,12 @@ class GroupedTab extends StatelessWidget {
}, },
); );
print(text); print(text);
if(text != null) if (text != null)
await javascriptExecutorBase.insertCheckbox(text); await javascriptExecutorBase.insertCheckbox(text);
}, },
), ),
TabButton( TabButton(
tooltip: 'Search',
icon: Icons.search, icon: Icons.search,
onTap: () async { onTap: () async {
// await javascriptExecutorBase.insertNumberedList(); // await javascriptExecutorBase.insertNumberedList();
@ -272,4 +315,10 @@ class GroupedTab extends StatelessWidget {
), ),
); );
} }
// Hide the keyboard using JavaScript since it's being opened in a WebView
// https://stackoverflow.com/a/8263376/10835183
_closeKeyboard() async {
// controller!.evaluateJavascript('document.activeElement.blur();');
}
} }