Skip to content

Commit 9e2c9fe

Browse files
authored
Merge pull request #50 from alexeyinkin/issue49_declarative-theme
Make theme declarative (#49)
2 parents a26301e + 0aeb31c commit 9e2c9fe

File tree

6 files changed

+112
-40
lines changed

6 files changed

+112
-40
lines changed

example/lib/custom_code_box.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ class _InnerFieldState extends State<InnerField> {
140140
"bev": TextStyle(color: Colors.indigo),
141141
},
142142
language: allLanguages[widget.language],
143-
theme: THEMES[widget.theme],
144143
);
145144
}
146145

@@ -152,6 +151,19 @@ class _InnerFieldState extends State<InnerField> {
152151

153152
@override
154153
Widget build(BuildContext context) {
154+
final styles = THEMES[widget.theme];
155+
156+
if (styles == null) {
157+
return _buildCodeField();
158+
}
159+
160+
return CodeTheme(
161+
data: CodeThemeData(styles: styles),
162+
child: _buildCodeField(),
163+
);
164+
}
165+
166+
Widget _buildCodeField() {
155167
return CodeField(
156168
controller: _codeController!,
157169
textStyle: TextStyle(fontFamily: 'SourceCode'),

example/lib/readme/readme_examples.dart

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ class _CodeEditorState extends State<CodeEditor> {
2525
_codeController = CodeController(
2626
text: source,
2727
language: dart,
28-
theme: monokaiSublimeTheme,
2928
);
3029
}
3130

@@ -37,10 +36,13 @@ class _CodeEditorState extends State<CodeEditor> {
3736

3837
@override
3938
Widget build(BuildContext context) {
40-
return CodeField(
41-
controller: _codeController!,
42-
textStyle: TextStyle(fontFamily: 'SourceCode'),
43-
expands: true,
39+
return CodeTheme(
40+
data: CodeThemeData(styles: monokaiSublimeTheme),
41+
child: CodeField(
42+
controller: _codeController!,
43+
textStyle: TextStyle(fontFamily: 'SourceCode'),
44+
expands: true,
45+
),
4446
);
4547
}
4648
}
@@ -61,7 +63,6 @@ class _CodeEditor1State extends State<CodeEditor1> {
6163
_codeController = CodeController(
6264
text: source,
6365
language: dart,
64-
theme: monokaiSublimeTheme,
6566
);
6667
}
6768

@@ -73,9 +74,12 @@ class _CodeEditor1State extends State<CodeEditor1> {
7374

7475
@override
7576
Widget build(BuildContext context) {
76-
return CodeField(
77-
controller: _codeController!,
78-
textStyle: TextStyle(fontFamily: 'SourceCode'),
77+
return CodeTheme(
78+
data: CodeThemeData(styles: monokaiSublimeTheme),
79+
child: CodeField(
80+
controller: _codeController!,
81+
textStyle: TextStyle(fontFamily: 'SourceCode'),
82+
),
7983
);
8084
}
8185
}
@@ -100,7 +104,6 @@ class _CodeEditor2State extends State<CodeEditor2> {
100104
_codeController = CodeController(
101105
text: source,
102106
language: dart,
103-
theme: monokaiSublimeTheme,
104107
stringMap: {
105108
"Hello": TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
106109
"world": TextStyle(fontStyle: FontStyle.italic, color: Colors.green),
@@ -116,9 +119,12 @@ class _CodeEditor2State extends State<CodeEditor2> {
116119

117120
@override
118121
Widget build(BuildContext context) {
119-
return CodeField(
120-
controller: _codeController!,
121-
textStyle: TextStyle(fontFamily: 'SourceCode'),
122+
return CodeTheme(
123+
data: CodeThemeData(styles: monokaiSublimeTheme),
124+
child: CodeField(
125+
controller: _codeController!,
126+
textStyle: TextStyle(fontFamily: 'SourceCode'),
127+
),
122128
);
123129
}
124130
}
@@ -143,7 +149,6 @@ class _CodeEditor3State extends State<CodeEditor3> {
143149
_codeController = CodeController(
144150
text: source,
145151
language: dart,
146-
theme: monokaiSublimeTheme,
147152
patternMap: {
148153
r"\B#[a-zA-Z0-9]+\b":
149154
TextStyle(fontWeight: FontWeight.bold, color: Colors.purpleAccent),
@@ -159,9 +164,12 @@ class _CodeEditor3State extends State<CodeEditor3> {
159164

160165
@override
161166
Widget build(BuildContext context) {
162-
return CodeField(
163-
controller: _codeController!,
164-
textStyle: TextStyle(fontFamily: 'SourceCode'),
167+
return CodeTheme(
168+
data: CodeThemeData(styles: monokaiSublimeTheme),
169+
child: CodeField(
170+
controller: _codeController!,
171+
textStyle: TextStyle(fontFamily: 'SourceCode'),
172+
),
165173
);
166174
}
167175
}
@@ -251,7 +259,6 @@ void main() {
251259
_codeController = CodeController(
252260
text: source,
253261
language: dart,
254-
theme: a11yDarkTheme,
255262
);
256263
}
257264

@@ -263,10 +270,13 @@ void main() {
263270

264271
@override
265272
Widget build(BuildContext context) {
266-
return CodeField(
267-
controller: _codeController!,
268-
textStyle: TextStyle(fontFamily: 'SourceCode'),
269-
expands: true,
273+
return CodeTheme(
274+
data: CodeThemeData(styles: a11yDarkTheme),
275+
child: CodeField(
276+
controller: _codeController!,
277+
textStyle: TextStyle(fontFamily: 'SourceCode'),
278+
expands: true,
279+
),
270280
);
271281
}
272282
}

lib/code_text_field.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export 'src/code_field.dart';
22
export 'src/code_controller.dart';
3+
export 'src/theme.dart';

lib/src/code_controller.dart

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import 'dart:math';
2-
import 'package:code_text_field/src/code_modifier.dart';
2+
3+
import 'package:flutter/foundation.dart' show kIsWeb;
34
import 'package:flutter/material.dart';
45
import 'package:flutter/services.dart';
56
import 'package:highlight/highlight_core.dart';
6-
import 'package:flutter/foundation.dart' show kIsWeb;
7+
8+
import 'code_modifier.dart';
9+
import 'theme.dart';
710

811
const _MIDDLE_DOT = '·';
912

@@ -36,8 +39,10 @@ class CodeController extends TextEditingController {
3639
Map<String, TextStyle>? _theme;
3740

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

45+
@Deprecated('Use CodeTheme widget to provide theme to CodeField.')
4146
set theme(Map<String, TextStyle>? theme) {
4247
if (theme == _theme) {
4348
return;
@@ -232,7 +237,7 @@ class CodeController extends TextEditingController {
232237
return TextSpan(style: style, children: children);
233238
}
234239

235-
TextSpan _processLanguage(String text, TextStyle? style) {
240+
TextSpan _processLanguage(String text, CodeThemeData? widgetTheme, TextStyle? style) {
236241
final rawText = _webSpaceFix ? _middleDotsToSpaces(text) : text;
237242
final result = highlight.parse(rawText, language: _languageId);
238243

@@ -245,16 +250,18 @@ class CodeController extends TextEditingController {
245250
void _traverse(Node node) {
246251
var val = node.value;
247252
final nodeChildren = node.children;
253+
final nodeStyle = widgetTheme?.styles[node.className] ?? _theme?[node.className];
254+
248255
if (val != null) {
249256
if (_webSpaceFix) val = _spacesToMiddleDots(val);
250-
var child = TextSpan(text: val, style: _theme?[node.className]);
251-
if (styleRegExp != null) child = _processPatterns(val, _theme?[node.className]);
257+
var child = TextSpan(text: val, style: nodeStyle);
258+
if (styleRegExp != null) child = _processPatterns(val, nodeStyle);
252259
currentSpans.add(child);
253260
} else if (nodeChildren != null) {
254261
List<TextSpan> tmp = [];
255262
currentSpans.add(TextSpan(
256263
children: tmp,
257-
style: _theme?[node.className],
264+
style: nodeStyle,
258265
));
259266
stack.add(currentSpans);
260267
currentSpans = tmp;
@@ -290,11 +297,14 @@ class CodeController extends TextEditingController {
290297
styleRegExp = RegExp(patternList.join('|'), multiLine: true);
291298

292299
// Return parsing
293-
if (_language != null && _theme != null)
294-
return _processLanguage(text, style);
295-
else if (styleRegExp != null)
300+
if (_language != null) {
301+
return _processLanguage(text, CodeTheme.of(context), style);
302+
}
303+
304+
if (styleRegExp != null) {
296305
return _processPatterns(text, style);
297-
else
298-
return TextSpan(text: text, style: style);
306+
}
307+
308+
return TextSpan(text: text, style: style);
299309
}
300310
}

lib/src/code_field.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import 'dart:math';
44
import 'package:flutter/material.dart';
55
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
66

7-
import './code_controller.dart';
7+
import 'code_controller.dart';
8+
import 'theme.dart';
89

910
class LineNumberController extends TextEditingController {
1011
final TextSpan Function(int, TextStyle?)? lineNumberBuilder;
@@ -243,25 +244,25 @@ class CodeFieldState extends State<CodeField> {
243244
final defaultBg = Colors.grey.shade900;
244245
final defaultText = Colors.grey.shade200;
245246

246-
final theme = widget.controller.theme;
247-
Color? backgroundCol = widget.background ?? theme?[ROOT_KEY]?.backgroundColor ?? defaultBg;
247+
final styles = CodeTheme.of(context)?.styles;
248+
Color? backgroundCol = widget.background ?? styles?[ROOT_KEY]?.backgroundColor ?? defaultBg;
248249
if (widget.decoration != null) {
249250
backgroundCol = null;
250251
}
251252
TextStyle textStyle = widget.textStyle ?? TextStyle();
252253
textStyle = textStyle.copyWith(
253-
color: textStyle.color ?? theme?[ROOT_KEY]?.color ?? defaultText,
254+
color: textStyle.color ?? styles?[ROOT_KEY]?.color ?? defaultText,
254255
fontSize: textStyle.fontSize ?? 16.0,
255256
);
256257
TextStyle numberTextStyle = widget.lineNumberStyle.textStyle ?? TextStyle();
257-
final numberColor = (theme?[ROOT_KEY]?.color ?? defaultText).withOpacity(0.7);
258+
final numberColor = (styles?[ROOT_KEY]?.color ?? defaultText).withOpacity(0.7);
258259
// Copy important attributes
259260
numberTextStyle = numberTextStyle.copyWith(
260261
color: numberTextStyle.color ?? numberColor,
261262
fontSize: textStyle.fontSize,
262263
fontFamily: textStyle.fontFamily,
263264
);
264-
final cursorColor = widget.cursorColor ?? theme?[ROOT_KEY]?.color ?? defaultText;
265+
final cursorColor = widget.cursorColor ?? styles?[ROOT_KEY]?.color ?? defaultText;
265266

266267
TextField? lineNumberCol;
267268
Container? numberCol;

lib/src/theme.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'package:flutter/widgets.dart';
2+
3+
class CodeThemeData {
4+
final Map<String, TextStyle> styles;
5+
6+
CodeThemeData({
7+
required this.styles,
8+
});
9+
10+
@override
11+
int get hashCode => styles.hashCode;
12+
13+
@override
14+
bool operator ==(Object other) {
15+
return identical(this, other) ||
16+
other is CodeThemeData && styles == other.styles;
17+
}
18+
}
19+
20+
class CodeTheme extends InheritedWidget {
21+
const CodeTheme({
22+
required this.data,
23+
Key? key,
24+
required Widget child,
25+
}) : super(key: key, child: child);
26+
27+
final CodeThemeData? data;
28+
29+
static CodeThemeData? of(BuildContext context) {
30+
final widget = context.dependOnInheritedWidgetOfExactType<CodeTheme>();
31+
return widget?.data;
32+
}
33+
34+
@override
35+
bool updateShouldNotify(covariant CodeTheme oldWidget) {
36+
return oldWidget.data != data;
37+
}
38+
}

0 commit comments

Comments
 (0)