feat: added more text commands

This commit is contained in:
jideguru
2021-05-28 01:41:07 +01:00
parent 87db96d65a
commit 25c6c39e1b
10 changed files with 695 additions and 17 deletions

View File

@@ -1,9 +1,5 @@
import 'package:flutter/material.dart';
extension ColorX on Color {
String toHexColorString() => '#${value.toString().replaceAll('ColorSwatch(',
'').replaceAll('Color(0xff', '').replaceAll('MaterialColor(', '')
.replaceAll('MaterialAccentColor(', '').replaceAll('primary value: '
'Color(0xff', '').replaceAll('primary', '').replaceAll('value:', '')
.replaceAll(')', '').trim()}';
String toHexColorString() => '#${value.toRadixString(16).replaceAll('ff', '')}';
}

View File

@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'custom_dialog_template.dart';
class CheckDialog extends StatelessWidget {
TextEditingController text = TextEditingController();
@override
Widget build(BuildContext context) {
return CustomDialogTemplate(
body: [
Text('Checkbox title'),
TextField(
controller: text,
decoration: InputDecoration(hintText: ''),
),
],
onDone: () => Navigator.pop(context, text.text),
onCancel: () => Navigator.pop(context),
);
}
}

View File

@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
class ColorPickerDialog extends StatefulWidget {
final Color? color;
ColorPickerDialog({this.color});
@override
_ColorPickerDialogState createState() => _ColorPickerDialogState();
}
class _ColorPickerDialogState extends State<ColorPickerDialog> {
Color? color;
@override
void initState() {
super.initState();
color = widget.color;
}
@override
Widget build(BuildContext context) {
return AlertDialog(
titlePadding: const EdgeInsets.all(0.0),
contentPadding: const EdgeInsets.all(0.0),
content: SingleChildScrollView(
child: ColorPicker(
pickerColor: color!,
onColorChanged: (pickedColor) {
color = pickedColor;
setState(() {});
},
colorPickerWidth: 300.0,
pickerAreaHeightPercent: 0.7,
enableAlpha: true,
displayThumbColor: true,
showLabel: true,
paletteType: PaletteType.hsv,
pickerAreaBorderRadius: const BorderRadius.only(
topLeft: const Radius.circular(2.0),
topRight: const Radius.circular(2.0),
),
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, color),
child: Text('Done'),
)
],
);
}
}

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
class FontsDialog extends StatelessWidget {
List fonts = [
{
'id': 'cursive',
'title': '<p style="font-family:cursive">This is a paragraph.</p>'
},
{
'id': 'monospace',
'title': '<p style="font-family:monospace">This is a paragraph.</p>'
}
];
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
for (Map font in fonts)
InkWell(
child: Html(data: font['title']),
onTap: () => Navigator.pop(context, font['id']),
)
],
);
}
}

View File

@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
class HeadingDialog extends StatelessWidget {
List formats = [
{'id': '1', 'title': '<h1>Heading 1</h1>'},
{'id': '2', 'title': '<h2>Heading 2</h2>'},
{'id': '3', 'title': '<h3>Heading 3</h3>'},
{'id': '4', 'title': '<h4>Heading 4</h4>'},
{'id': '5', 'title': '<h5>Heading 5</h5>'},
{'id': '6', 'title': '<h6>Heading 6</h6>'},
{'id': 'p', 'title': '<p>Text body</p>'},
{
'id': 'pre',
'title': '<pre><font face=\"courier\">Preformat</font></pre>'
},
{'id': 'blockquote', 'title': '<blockquote>Quote</blockquote>'},
];
@override
Widget build(BuildContext context) {
return 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

@@ -1,10 +1,15 @@
import 'package:flutter/material.dart';
import 'package:rich_editor/src/utils/javascript_executor_base.dart';
import 'package:rich_editor/src/widgets/check_dialog.dart';
import 'package:rich_editor/src/widgets/fonts_dialog.dart';
import 'package:rich_editor/src/widgets/insert_image_dialog.dart';
import 'package:rich_editor/src/widgets/insert_link_dialog.dart';
import 'package:rich_editor/src/widgets/tab_button.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'color_picker_dialog.dart';
import 'heading_dialog.dart';
class GroupedTab extends StatelessWidget {
final WebViewController? controller;
@@ -102,25 +107,164 @@ class GroupedTab extends StatelessWidget {
await javascriptExecutorBase.removeFormat();
},
),
TabButton(
icon: Icons.undo,
onTap: () async {
await javascriptExecutorBase.undo();
},
),
TabButton(
icon: Icons.redo,
onTap: () async {
await javascriptExecutorBase.redo();
},
),
TabButton(
icon: Icons.undo,
onTap: () async {
await javascriptExecutorBase.undo();
},
),
TabButton(
icon: Icons.format_quote,
onTap: () async {
await javascriptExecutorBase.setBlockQuote();
},
),
TabButton(
icon: Icons.text_format,
onTap: () async {
var command = await showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (_) {
return HeadingDialog();
},
);
if (command != null) {
if (command == 'p') {
await javascriptExecutorBase.setFormattingToParagraph();
} else if (command == 'pre') {
await javascriptExecutorBase.setPreformat();
} else if (command == 'blockquote') {
await javascriptExecutorBase.setBlockQuote();
} else {
await javascriptExecutorBase
.setHeading(int.tryParse(command)!);
}
}
},
),
TabButton(
icon: Icons.font_download,
onTap: () async {
var command = await showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (_) {
return FontsDialog();
},
);
if (command != null)
await javascriptExecutorBase.setFontName(command);
},
),
TabButton(
icon: Icons.format_size,
onTap: () async {
await javascriptExecutorBase.setFontSize(7);
},
),
TabButton(
icon: Icons.format_color_text,
onTap: () async {
var color = await showDialog(
context: context,
builder: (BuildContext context) {
return ColorPickerDialog(color: Colors.blue);
},
);
if (color != null)
await javascriptExecutorBase.setTextColor(color);
},
),
TabButton(
icon: Icons.format_color_fill,
onTap: () async {
var color = await showDialog(
context: context,
builder: (BuildContext context) {
return ColorPickerDialog(color: Colors.blue);
},
);
if (color != null)
await javascriptExecutorBase
.setTextBackgroundColor(color);
},
),
TabButton(
icon: Icons.format_indent_increase,
onTap: () async {
await javascriptExecutorBase.setIndent();
},
),
TabButton(
icon: Icons.format_indent_decrease,
onTap: () async {
await javascriptExecutorBase.setOutdent();
},
),
TabButton(
icon: Icons.format_align_left_outlined,
onTap: () async {
await javascriptExecutorBase.setJustifyLeft();
},
),
TabButton(
icon: Icons.format_align_center,
onTap: () async {
await javascriptExecutorBase.setJustifyCenter();
},
),
TabButton(
icon: Icons.format_align_right,
onTap: () async {
await javascriptExecutorBase.setJustifyRight();
},
),
TabButton(
icon: Icons.format_align_justify,
onTap: () async {
await javascriptExecutorBase.setJustifyFull();
},
),
TabButton(
icon: Icons.format_list_bulleted,
onTap: () async {
await javascriptExecutorBase.insertBulletList();
},
),
TabButton(
icon: Icons.format_list_numbered,
onTap: () async {
await javascriptExecutorBase.insertNumberedList();
},
),
TabButton(
icon: Icons.check_box_outlined,
onTap: () async {
var text = await showDialog(
context: context,
builder: (BuildContext context) {
return CheckDialog();
},
);
print(text);
if(text != null)
await javascriptExecutorBase.insertCheckbox(text);
},
),
TabButton(
icon: Icons.search,
onTap: () async {
// await javascriptExecutorBase.insertNumberedList();
},
),
],
),
),