mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 02:07:39 +08:00
MarkdownToolBar: First attempt at the toolbar
This can be enabled via 'Settings -> Experimental'. It's very rough right now and a lot still needs to be done. Related to #157
This commit is contained in:
@ -62,6 +62,7 @@ settings:
|
|||||||
subtitle: Try out features in Development
|
subtitle: Try out features in Development
|
||||||
backlinks: Show Backlinks in Markdown Preview
|
backlinks: Show Backlinks in Markdown Preview
|
||||||
fs: Show File System
|
fs: Show File System
|
||||||
|
markdownToolbar: Show Markdown Toolbar in Editor
|
||||||
editors:
|
editors:
|
||||||
title: Editor Settings
|
title: Editor Settings
|
||||||
subtitle: Configure how different editors work
|
subtitle: Configure how different editors work
|
||||||
|
@ -129,6 +129,23 @@ class MarkdownEditorState extends State<MarkdownEditor>
|
|||||||
|
|
||||||
Widget body = editingMode ? editor : NoteViewer(note: note);
|
Widget body = editingMode ? editor : NoteViewer(note: note);
|
||||||
|
|
||||||
|
if (Settings.instance.experimentalMarkdownToolbar && editingMode) {
|
||||||
|
body = Container(
|
||||||
|
height: 600,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(child: editor),
|
||||||
|
MarkdownToolBar(
|
||||||
|
onHeader1: () => _modifyCurrentLine('# '),
|
||||||
|
onItallics: () => _modifyCurrentWord('*'),
|
||||||
|
onBold: () => _modifyCurrentWord('**'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var extraButton = IconButton(
|
var extraButton = IconButton(
|
||||||
icon: editingMode
|
icon: editingMode
|
||||||
? const Icon(Icons.remove_red_eye)
|
? const Icon(Icons.remove_red_eye)
|
||||||
@ -226,4 +243,126 @@ class MarkdownEditorState extends State<MarkdownEditor>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool get noteModified => _noteModified;
|
bool get noteModified => _noteModified;
|
||||||
|
|
||||||
|
void _modifyCurrentLine(String char) {
|
||||||
|
var selection = _textController.value.selection;
|
||||||
|
var text = _textController.value.text;
|
||||||
|
|
||||||
|
print('Base offset: ${selection.baseOffset}');
|
||||||
|
print('Extent offset: ${selection.extentOffset}');
|
||||||
|
var cursorPos = selection.baseOffset;
|
||||||
|
if (cursorPos == -1) {
|
||||||
|
cursorPos = 0;
|
||||||
|
}
|
||||||
|
print('CursorPos: $cursorPos');
|
||||||
|
|
||||||
|
var lineStartPos =
|
||||||
|
text.lastIndexOf('\n', cursorPos == 0 ? 0 : cursorPos - 1);
|
||||||
|
if (lineStartPos == -1) {
|
||||||
|
lineStartPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lineEndPos = text.indexOf('\n', cursorPos);
|
||||||
|
if (lineEndPos == -1) {
|
||||||
|
lineEndPos = text.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
print('Line Start: $lineStartPos');
|
||||||
|
print('Line End: $lineEndPos');
|
||||||
|
print('Line: ${text.substring(lineStartPos, lineEndPos)}');
|
||||||
|
|
||||||
|
// Check if already present
|
||||||
|
if (text.startsWith(char, lineStartPos)) {
|
||||||
|
print('Removing `$char`');
|
||||||
|
_textController.text = text.replaceFirst(char, '', lineStartPos);
|
||||||
|
_textController.selection =
|
||||||
|
TextSelection.collapsed(offset: cursorPos - char.length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print('Adding `$char`');
|
||||||
|
_textController.text = text.replaceRange(lineStartPos, lineStartPos, char);
|
||||||
|
_textController.selection =
|
||||||
|
TextSelection.collapsed(offset: cursorPos + char.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _modifyCurrentWord(String char) {
|
||||||
|
var selection = _textController.value.selection;
|
||||||
|
var text = _textController.value.text;
|
||||||
|
|
||||||
|
print('Base offset: ${selection.baseOffset}');
|
||||||
|
print('Extent offset: ${selection.extentOffset}');
|
||||||
|
var cursorPos = selection.baseOffset;
|
||||||
|
if (cursorPos == -1) {
|
||||||
|
cursorPos = 0;
|
||||||
|
}
|
||||||
|
print('CursorPos: $cursorPos');
|
||||||
|
|
||||||
|
var wordStartPos =
|
||||||
|
text.lastIndexOf(' ', cursorPos == 0 ? 0 : cursorPos - 1);
|
||||||
|
if (wordStartPos == -1) {
|
||||||
|
wordStartPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wordEndPos = text.indexOf(' ', cursorPos);
|
||||||
|
if (wordEndPos == -1) {
|
||||||
|
wordEndPos = text.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
print('Word Start: $wordStartPos');
|
||||||
|
print('Word End: $wordEndPos');
|
||||||
|
print('Word: ${text.substring(wordStartPos, wordEndPos)}');
|
||||||
|
|
||||||
|
// Check if already present
|
||||||
|
if (text.startsWith(char, wordStartPos)) {
|
||||||
|
print('Removing `$char`');
|
||||||
|
_textController.text = text.replaceFirst(char, '', wordStartPos);
|
||||||
|
_textController.selection =
|
||||||
|
TextSelection.collapsed(offset: cursorPos - (char.length * 2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print('Adding `$char`');
|
||||||
|
_textController.text = text.replaceRange(wordStartPos, wordStartPos, char);
|
||||||
|
wordEndPos += char.length;
|
||||||
|
|
||||||
|
_textController.text =
|
||||||
|
text.replaceRange(wordEndPos - 1, wordEndPos - 1, char);
|
||||||
|
_textController.selection =
|
||||||
|
TextSelection.collapsed(offset: cursorPos + (char.length * 2));
|
||||||
|
|
||||||
|
print('$char');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MarkdownToolBar extends StatelessWidget {
|
||||||
|
final Function onHeader1;
|
||||||
|
final Function onItallics;
|
||||||
|
final Function onBold;
|
||||||
|
|
||||||
|
MarkdownToolBar({
|
||||||
|
@required this.onHeader1,
|
||||||
|
@required this.onItallics,
|
||||||
|
@required this.onBold,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Text('H1'),
|
||||||
|
onPressed: onHeader1,
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Text('I'),
|
||||||
|
onPressed: onItallics,
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Text('B'),
|
||||||
|
onPressed: onBold,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,15 @@ class _ExperimentalSettingsScreenState
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SwitchListTile(
|
||||||
|
title: Text(tr('settings.experimental.markdownToolbar')),
|
||||||
|
value: settings.experimentalFs,
|
||||||
|
onChanged: (bool newVal) {
|
||||||
|
settings.experimentalFs = newVal;
|
||||||
|
settings.save();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
padding: const EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 0.0),
|
padding: const EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 0.0),
|
||||||
),
|
),
|
||||||
|
@ -54,6 +54,7 @@ class Settings {
|
|||||||
|
|
||||||
bool experimentalBacklinks = true;
|
bool experimentalBacklinks = true;
|
||||||
bool experimentalFs = false;
|
bool experimentalFs = false;
|
||||||
|
bool experimentalMarkdownToolbar = false;
|
||||||
|
|
||||||
bool zenMode = false;
|
bool zenMode = false;
|
||||||
bool saveTitleInH1 = true;
|
bool saveTitleInH1 = true;
|
||||||
@ -123,6 +124,8 @@ class Settings {
|
|||||||
experimentalBacklinks =
|
experimentalBacklinks =
|
||||||
pref.getBool("experimentalBacklinks") ?? experimentalBacklinks;
|
pref.getBool("experimentalBacklinks") ?? experimentalBacklinks;
|
||||||
experimentalFs = pref.getBool("experimentalFs") ?? experimentalFs;
|
experimentalFs = pref.getBool("experimentalFs") ?? experimentalFs;
|
||||||
|
experimentalMarkdownToolbar = pref.getBool("experimentalMarkdownToolbar") ??
|
||||||
|
experimentalMarkdownToolbar;
|
||||||
|
|
||||||
zenMode = pref.getBool("zenMode") ?? zenMode;
|
zenMode = pref.getBool("zenMode") ?? zenMode;
|
||||||
saveTitleInH1 = pref.getBool("saveTitleInH1") ?? saveTitleInH1;
|
saveTitleInH1 = pref.getBool("saveTitleInH1") ?? saveTitleInH1;
|
||||||
@ -194,6 +197,8 @@ class Settings {
|
|||||||
_setBool(pref, "experimentalBacklinks", experimentalBacklinks,
|
_setBool(pref, "experimentalBacklinks", experimentalBacklinks,
|
||||||
defaultSet.experimentalBacklinks);
|
defaultSet.experimentalBacklinks);
|
||||||
_setBool(pref, "experimentalFs", experimentalFs, defaultSet.experimentalFs);
|
_setBool(pref, "experimentalFs", experimentalFs, defaultSet.experimentalFs);
|
||||||
|
_setBool(pref, "experimentalMarkdownToolbar", experimentalMarkdownToolbar,
|
||||||
|
defaultSet.experimentalMarkdownToolbar);
|
||||||
_setBool(pref, "zenMode", zenMode, defaultSet.zenMode);
|
_setBool(pref, "zenMode", zenMode, defaultSet.zenMode);
|
||||||
_setBool(pref, "saveTitleInH1", saveTitleInH1, defaultSet.saveTitleInH1);
|
_setBool(pref, "saveTitleInH1", saveTitleInH1, defaultSet.saveTitleInH1);
|
||||||
|
|
||||||
@ -257,6 +262,7 @@ class Settings {
|
|||||||
'debugLogLevel': debugLogLevel,
|
'debugLogLevel': debugLogLevel,
|
||||||
'experimentalBacklinks': experimentalBacklinks.toString(),
|
'experimentalBacklinks': experimentalBacklinks.toString(),
|
||||||
'experimentalFs': experimentalFs.toString(),
|
'experimentalFs': experimentalFs.toString(),
|
||||||
|
'experimentalMarkdownToolbar': experimentalMarkdownToolbar.toString(),
|
||||||
'zenMode': zenMode.toString(),
|
'zenMode': zenMode.toString(),
|
||||||
'saveTitleInH1': saveTitleInH1.toString(),
|
'saveTitleInH1': saveTitleInH1.toString(),
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user