Skip to content

Commit

Permalink
Merge branch '20220701_theme-from-widget' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyinkin committed Jul 5, 2022
2 parents 4c67fa6 + 3fcc2ea commit 9a4f5aa
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 35 deletions.
1 change: 1 addition & 0 deletions lib/code_text_field.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'src/code_field.dart';
export 'src/code_controller.dart';
export 'src/theme.dart';
93 changes: 66 additions & 27 deletions lib/src/code_controller.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import 'dart:math';

import 'package:code_text_field/languages/main_mode.dart';
import 'package:code_text_field/src/autocomplete/popup_controller.dart';
import 'package:code_text_field/src/autocomplete/suggestion.dart';
import 'package:code_text_field/src/autocomplete/suggestion_generator.dart';
import 'package:code_text_field/src/code_modifier.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:highlight/highlight_core.dart';
import 'package:code_text_field/languages/main_mode.dart';

import 'code_modifier.dart';
import 'theme.dart';

const _MIDDLE_DOT = '·';

Expand All @@ -19,11 +21,40 @@ class EditorParams {
}

class CodeController extends TextEditingController {
/// A highligh language to parse the text with
final MainMode? language;
MainMode? _language;

/// A highlight language to parse the text with
MainMode? get language => _language;

set language(MainMode? language) {
if (language == _language) {
return;
}

if (language != null) {
_languageId = _genId();
highlight.registerLanguage(_languageId, language);
}

_language = language;
notifyListeners();
}

Map<String, TextStyle>? _theme;

/// The theme to apply to the [language] parsing result
final Map<String, TextStyle>? theme;
@Deprecated('Use CodeTheme widget to provide theme to CodeField.')
Map<String, TextStyle>? get theme => _theme;

@Deprecated('Use CodeTheme widget to provide theme to CodeField.')
set theme(Map<String, TextStyle>? theme) {
if (theme == _theme) {
return;
}

_theme = theme;
notifyListeners();
}

/// A map of specific regexes to style
final Map<String, TextStyle>? patternMap;
Expand All @@ -48,7 +79,10 @@ class CodeController extends TextEditingController {
final void Function(String)? onChange;

/* Computed members */
final String languageId = _genId();
String _languageId = _genId();

String get languageId => _languageId;

final styleList = <TextStyle>[];
final modifierMap = <String, CodeModifier>{};
bool isPopupShown = false;
Expand All @@ -58,8 +92,8 @@ class CodeController extends TextEditingController {

CodeController({
String? text,
this.language,
this.theme,
MainMode? language,
Map<String, TextStyle>? theme,
this.patternMap,
this.stringMap,
this.params = const EditorParams(),
Expand All @@ -70,14 +104,10 @@ class CodeController extends TextEditingController {
],
this.webSpaceFix = true,
this.onChange,
}) : super(text: text) {
// PatternMap
if (language != null && theme == null)
throw Exception("A theme must be provided for language parsing");
// Register language
if (language != null) {
highlight.registerLanguage(languageId, language!);
}
}) : _theme = theme,
super(text: text) {
this.language = language;

// Create modifier map
modifiers.forEach((el) {
modifierMap[el.char] = el;
Expand All @@ -87,6 +117,11 @@ class CodeController extends TextEditingController {
this.popupController = PopupController(onCompletionSelected: this.insertSelectedWord);
}

/// Sets a specific cursor position in the text
void setCursor(int offset) {
selection = TextSelection.collapsed(offset: offset);
}

/// Replaces the current [selection] by [str]
void insertStr(String str) {
final sel = selection;
Expand Down Expand Up @@ -259,9 +294,9 @@ class CodeController extends TextEditingController {
return TextSpan(style: style, children: children);
}

TextSpan _processLanguage(String text, TextStyle? style) {
TextSpan _processLanguage(String text, CodeThemeData? widgetTheme, TextStyle? style) {
final rawText = _webSpaceFix ? _middleDotsToSpaces(text) : text;
final result = highlight.parse(rawText, language: languageId);
final result = highlight.parse(rawText, language: _languageId);

final nodes = result.nodes;

Expand All @@ -272,17 +307,18 @@ class CodeController extends TextEditingController {
void _traverse(Node node) {
var val = node.value;
final nodeChildren = node.children;
final nodeStyle = widgetTheme?.styles[node.className] ?? _theme?[node.className];

if (val != null) {
if (_webSpaceFix) val = _spacesToMiddleDots(val);
var child = TextSpan(text: val, style: theme?[node.className]);
if (styleRegExp != null)
child = _processPatterns(val, theme?[node.className]);
var child = TextSpan(text: val, style: nodeStyle);
if (styleRegExp != null) child = _processPatterns(val, nodeStyle);
currentSpans.add(child);
} else if (nodeChildren != null) {
List<TextSpan> tmp = [];
currentSpans.add(TextSpan(
children: tmp,
style: theme?[node.className],
style: nodeStyle,
));
stack.add(currentSpans);
currentSpans = tmp;
Expand Down Expand Up @@ -328,11 +364,14 @@ class CodeController extends TextEditingController {
styleRegExp = RegExp(patternList.join('|'), multiLine: true);

// Return parsing
if (language != null)
return _processLanguage(text, style);
else if (styleRegExp != null)
if (_language != null) {
return _processLanguage(text, CodeTheme.of(context), style);
}

if (styleRegExp != null) {
return _processPatterns(text, style);
else
return TextSpan(text: text, style: style);
}

return TextSpan(text: text, style: style);
}
}
16 changes: 8 additions & 8 deletions lib/src/code_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:linked_scroll_controller/linked_scroll_controller.dart';

import 'code_controller.dart';
import 'theme.dart';

import '/language_syntax/brackets_counting.dart';
import '/language_syntax/java_dart_syntax.dart';
Expand Down Expand Up @@ -191,7 +192,7 @@ class CodeField extends StatefulWidget {
}

class CodeFieldState extends State<CodeField> {
// Add a controller
// Add a controller
LinkedScrollControllerGroup? _controllers;
ScrollController? _numberScroll;
ScrollController? _codeScroll;
Expand Down Expand Up @@ -321,29 +322,28 @@ class CodeFieldState extends State<CodeField> {
final defaultBg = Colors.grey.shade900;
final defaultText = Colors.grey.shade200;

final theme = widget.controller.theme;
final styles = CodeTheme.of(context)?.styles;
Color? backgroundCol =
widget.background ?? theme?[ROOT_KEY]?.backgroundColor ?? defaultBg;
widget.background ?? styles?[ROOT_KEY]?.backgroundColor ?? defaultBg;
if (widget.decoration != null) {
backgroundCol = null;
}
TextStyle textStyle = widget.textStyle ?? TextStyle();
textStyle = textStyle.copyWith(
color: textStyle.color ?? theme?[ROOT_KEY]?.color ?? defaultText,
color: textStyle.color ?? styles?[ROOT_KEY]?.color ?? defaultText,
fontSize: textStyle.fontSize ?? this.widget.defaultFontSize,
);
this.widget.textStyle = textStyle;
TextStyle numberTextStyle = widget.lineNumberStyle.textStyle ?? TextStyle();
final numberColor =
(theme?[ROOT_KEY]?.color ?? defaultText).withOpacity(0.7);
final numberColor = (styles?[ROOT_KEY]?.color ?? defaultText).withOpacity(0.7);
// Copy important attributes
numberTextStyle = numberTextStyle.copyWith(
color: numberTextStyle.color ?? numberColor,
fontSize: textStyle.fontSize,
fontFamily: textStyle.fontFamily,
);
final cursorColor =
widget.cursorColor ?? theme?[ROOT_KEY]?.color ?? defaultText;
widget.cursorColor ?? styles?[ROOT_KEY]?.color ?? defaultText;

final lineNumberCol = TextField(
scrollPadding: widget.padding,
Expand Down Expand Up @@ -381,8 +381,8 @@ class CodeFieldState extends State<CodeField> {
controller: widget.controller,
minLines: widget.minLines,
maxLines: widget.maxLines,
scrollController: _codeScroll,
expands: widget.expands,
scrollController: _codeScroll,
decoration: InputDecoration(
isCollapsed: true,
contentPadding: EdgeInsets.symmetric(vertical: 16.0),
Expand Down

0 comments on commit 9a4f5aa

Please sign in to comment.