Add fonts (#35)

This commit is contained in:
Oystein Kristoffer Tveit 2022-01-23 23:56:26 +01:00 committed by GitHub
parent a577af2667
commit f6134c07a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 267 additions and 83 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
class DenshiJishoBackground extends StatelessWidget {
final Widget child;
const DenshiJishoBackground({
Key? key,
required this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
right: 30,
left: 100,
bottom: 30,
child: Image.asset(
'assets/images/denshi_jisho_background_overlay.png',
),
),
child,
],
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:signature/signature.dart';
import '../../bloc/theme/theme_bloc.dart';
import '../../services/handwriting.dart';
import '../../settings.dart';
class DrawingBoard extends StatefulWidget {
final Function(String)? onSuggestionChosen;
@ -112,7 +113,7 @@ class _DrawingBoardState extends State<DrawingBoard> {
style: TextStyle(
fontSize: fontSize,
color: colors.foreground,
),
).merge(japaneseFont.textStyle),
),
),
);

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import '../../models/history/search.dart';
import '../../settings.dart';
class SearchItem extends StatelessWidget {
final DateTime time;
@ -67,7 +68,10 @@ class SearchItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Text(getTime()),
),
search,
DefaultTextStyle.merge(
style: japaneseFont.textStyle,
child: search,
),
],
),
),

View File

@ -122,7 +122,7 @@ class _Kana extends StatelessWidget {
style: TextStyle(
color: colors.foreground,
fontSize: 15.0,
),
).merge(!romajiEnabled ? japaneseFont.textStyle : null),
),
const SizedBox(height: 5.0),
Text(
@ -130,7 +130,7 @@ class _Kana extends StatelessWidget {
style: TextStyle(
color: colors.foreground,
fontSize: 20.0,
),
).merge(japaneseFont.textStyle),
),
],
),

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import '../../../bloc/theme/theme_bloc.dart';
import '../../../settings.dart';
class Grade extends StatelessWidget {
final String? grade;
@ -28,7 +29,7 @@ class Grade extends StatelessWidget {
style: TextStyle(
color: colors.foreground,
fontSize: 20.0,
),
).merge(japaneseFont.textStyle),
),
);
},

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import '../../../bloc/theme/theme_bloc.dart';
import '../../../settings.dart';
class Header extends StatelessWidget {
final String kanji;
@ -25,7 +26,8 @@ class Header extends StatelessWidget {
),
child: Text(
kanji,
style: TextStyle(fontSize: 70.0, color: colors.foreground),
style: TextStyle(fontSize: 70.0, color: colors.foreground)
.merge(japaneseFont.textStyle),
),
);
},

View File

@ -3,6 +3,7 @@ import 'package:unofficial_jisho_api/api.dart' as jisho;
import '../../../bloc/theme/theme_bloc.dart';
import '../../../routing/routes.dart';
import '../../../settings.dart';
class Radical extends StatelessWidget {
final jisho.Radical radical;
@ -30,7 +31,7 @@ class Radical extends StatelessWidget {
style: TextStyle(
color: colors.foreground,
fontSize: 40.0,
),
).merge(japaneseFont.textStyle),
),
),
);

View File

@ -54,6 +54,7 @@ class YomiChips extends StatelessWidget {
required BuildContext context,
required String yomi,
required ColorSet colors,
TextStyle? extraTextStyle,
}) =>
InkWell(
onTap: () =>
@ -73,7 +74,7 @@ class YomiChips extends StatelessWidget {
style: TextStyle(
fontSize: 20.0,
color: colors.foreground,
),
).merge(extraTextStyle),
),
),
);
@ -86,6 +87,9 @@ class YomiChips extends StatelessWidget {
context: context,
yomi: y,
colors: type.getColors(context),
extraTextStyle: type != YomiType.meaning && !romajiEnabled
? japaneseFont.textStyle
: null,
),
)
.toList();

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import '../../../bloc/theme/theme_bloc.dart';
import '../../../routing/routes.dart';
import '../../../settings.dart';
class KanjiGrid extends StatelessWidget {
final List<String> suggestions;
@ -49,7 +50,9 @@ class _GridItem extends StatelessWidget {
child: FittedBox(
child: Text(
kanji,
style: TextStyle(color: _menuColors.foreground),
style: japaneseFont.textStyle.merge(
TextStyle(color: _menuColors.foreground),
),
),
),
),

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../../settings.dart';
class KanjiSearchBar extends StatefulWidget {
final Function(String)? onChanged;
@ -52,6 +54,7 @@ class KanjiSearchBarState extends State<KanjiSearchBar> {
controller: textController,
onChanged: (text) => onChanged(),
onSubmitted: (_) => {},
style: japaneseFont.textStyle,
decoration: InputDecoration(
hintText: 'Search',
border: OutlineInputBorder(

View File

@ -3,6 +3,7 @@ import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../models/themes/theme.dart';
import '../../settings.dart';
class LanguageSelector extends StatefulWidget {
const LanguageSelector({Key? key}) : super(key: key);
@ -31,11 +32,11 @@ class _LanguageSelectorState extends State<LanguageSelector> {
?.map((s) => s == '1')
.toList();
Widget _languageOption(String language) =>
Widget _languageOption(String language, {TextStyle? style}) =>
Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Text(language),
child: Text(language, style: style,),
);
@override
@ -43,9 +44,9 @@ class _LanguageSelectorState extends State<LanguageSelector> {
return ToggleButtons(
selectedColor: AppTheme.jishoGreen.background,
isSelected: isSelected,
children: <Widget>[
children: [
_languageOption('Auto'),
_languageOption('日本語'),
_languageOption('日本語', style: japaneseFont.textStyle),
_languageOption('English')
],
onPressed: (buttonIndex) {

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import '../../models/themes/theme.dart';
import '../../routing/routes.dart';
import '../../settings.dart';
import 'language_selector.dart';
class SearchBar extends StatelessWidget {
@ -24,6 +25,7 @@ class SearchBar extends StatelessWidget {
TextField(
onSubmitted: (text) => _search(context, text),
controller: controller,
style: japaneseFont.textStyle,
decoration: InputDecoration(
labelText: 'Search',
border: OutlineInputBorder(

View File

@ -31,8 +31,23 @@ class JapaneseHeader extends StatelessWidget {
// If that's not the case, then the word is usually present in wordReading.
// However, there are some exceptions where the reading is placed in word.
// I have no clue why this might be the case.
hasFurigana ? Text(wordReading!) : const Text(''),
hasFurigana ? Text(word.word!) : Text(wordReading ?? word.word!),
hasFurigana
? Text(
wordReading!,
style: romajiEnabled ? null : japaneseFont.textStyle,
)
: const Text(''),
hasFurigana
? Text(
word.word!,
style: japaneseFont.textStyle,
)
: Text(
wordReading ?? word.word!,
style: wordReading != null && romajiEnabled
? null
: japaneseFont.textStyle,
),
],
),
);

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import '../../../../bloc/theme/theme_bloc.dart';
import '../../../../routing/routes.dart';
import '../../../../settings.dart';
class KanjiRow extends StatelessWidget {
final List<String> kanji;
@ -32,7 +33,7 @@ class KanjiRow extends StatelessWidget {
style: TextStyle(
color: colors.foreground,
fontSize: fontSize,
),
).merge(japaneseFont.textStyle),
),
),
);

View File

@ -65,6 +65,10 @@ class KanjiKanaBox extends StatelessWidget {
style: TextStyle(
fontSize: fFontsize,
color: colors.foreground,
).merge(
romajiEnabled && autoTransliterateRomaji
? null
: japaneseFont.textStyle,
),
)
: Text(
@ -77,9 +81,10 @@ class KanjiKanaBox extends StatelessWidget {
DefaultTextStyle.merge(
child: hasFurigana
? Text(word.word!)
? Text(word.word ?? word.reading!)
: Text(wordReading ?? word.word!),
style: TextStyle(fontSize: kanjiFontsize),
style: TextStyle(fontSize: kanjiFontsize)
.merge(japaneseFont.textStyle),
),
if (romajiEnabled && showRomajiBelow)
Text(

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import '../../../../../models/themes/theme.dart';
import '../../../../../routing/routes.dart';
import '../../../../../settings.dart';
import 'search_chip.dart';
class Antonyms extends StatelessWidget {
@ -41,6 +42,7 @@ class Antonyms extends StatelessWidget {
child: SearchChip(
text: antonym,
colors: colors,
extraTextStyle: japaneseFont.textStyle,
),
),
],

View File

@ -5,11 +5,13 @@ import '../../../../../models/themes/theme.dart';
class SearchChip extends StatelessWidget {
final String text;
final ColorSet colors;
final TextStyle? extraTextStyle;
const SearchChip({
Key? key,
required this.text,
this.colors = LightTheme.defaultMenuGreyNormal,
this.extraTextStyle,
}) : super(key: key);
@override
@ -21,7 +23,7 @@ class SearchChip extends StatelessWidget {
),
child: Text(
text,
style: TextStyle(color: colors.foreground),
style: TextStyle(color: colors.foreground).merge(extraTextStyle),
),
);
}

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:unofficial_jisho_api/api.dart';
import '../../../../../settings.dart';
class SupplementalInfo extends StatelessWidget {
final JishoWordSense sense;
final List<String>? supplementalInfo;
@ -42,6 +44,6 @@ class SupplementalInfo extends StatelessWidget {
@override
Widget build(BuildContext context) => DefaultTextStyle.merge(
child: Column(children: _body),
style: TextStyle(color: color),
style: TextStyle(color: color).merge(japaneseFont.textStyle),
);
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:mdi/mdi.dart';
import '../bloc/theme/theme_bloc.dart';
import '../components/common/denshi_jisho_background.dart';
import 'debug.dart';
import 'history.dart';
import 'search/kanji_view.dart';
@ -30,19 +31,7 @@ class _HomeState extends State<Home> {
backgroundColor: AppTheme.jishoGreen.background,
foregroundColor: AppTheme.jishoGreen.foreground,
),
body: Stack(
children: [
Positioned(
right: 30,
left: 100,
bottom: 30,
child: Image.asset(
'assets/images/denshi_jisho_background_overlay.png',
),
),
pages[pageNum].content,
],
),
body: DenshiJishoBackground(child: pages[pageNum].content),
bottomNavigationBar: BottomNavigationBar(
fixedColor: AppTheme.jishoGreen.background,
currentIndex: pageNum,
@ -103,8 +92,8 @@ class _HomeState extends State<Home> {
if (kDebugMode) ...[
const _Page(
content: DebugView(),
titleBar: Text('Debug Page'),
item: BottomNavigationBarItem(
titleBar: Text('Debug Page'),
item: BottomNavigationBarItem(
label: 'Debug',
icon: Icon(Icons.biotech),
),

View File

@ -5,6 +5,7 @@ import '../../../../data/grades.dart';
import '../../../../models/themes/theme.dart';
import '../../../../routing/routes.dart';
import '../../../components/common/loading.dart';
import '../../../settings.dart';
class KanjiGradeSearch extends StatefulWidget {
const KanjiGradeSearch({Key? key}) : super(key: key);
@ -48,7 +49,7 @@ class _GridItem extends StatelessWidget {
style: TextStyle(
color: color.foreground,
fontSize: 25,
),
).merge(japaneseFont.textStyle),
),
),
);

View File

@ -4,6 +4,7 @@ import '../../../../bloc/theme/theme_bloc.dart';
import '../../../../data/radicals.dart';
import '../../../../routing/routes.dart';
import '../../../../services/jisho_api/radicals_search.dart';
import '../../../settings.dart';
class KanjiRadicalSearch extends StatefulWidget {
final String? prechosenRadical;
@ -32,7 +33,7 @@ class _KanjiRadicalSearchState extends State<KanjiRadicalSearch> {
if (widget.prechosenRadical != null &&
radicalToggles.containsKey(widget.prechosenRadical))
radicalToggles[widget.prechosenRadical!] = true;
updateSuggestions();
updateSuggestions();
super.initState();
}
@ -162,47 +163,50 @@ class _KanjiRadicalSearchState extends State<KanjiRadicalSearch> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Choose by radicals')),
body: Column(
children: [
Expanded(
child: (suggestions.isEmpty)
? Center(
child: BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, state) => Text(
'Toggle a radical to start',
style: TextStyle(
fontSize: fontSize * 0.8,
color: state.theme.menuGreyNormal.background,
body: DefaultTextStyle.merge(
style: japaneseFont.textStyle,
child: Column(
children: [
Expanded(
child: (suggestions.isEmpty)
? Center(
child: BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, state) => Text(
'Toggle a radical to start',
style: TextStyle(
fontSize: fontSize * 0.8,
color: state.theme.menuGreyNormal.background,
),
),
),
)
: GridView.count(
crossAxisCount: 6,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
padding: const EdgeInsets.all(10),
children:
suggestions.map((s) => kanjiGridElement(s)).toList(),
),
)
: GridView.count(
crossAxisCount: 6,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
padding: const EdgeInsets.all(10),
children:
suggestions.map((s) => kanjiGridElement(s)).toList(),
),
),
Divider(
color: AppTheme.jishoGreen.background,
thickness: 3,
height: 30,
indent: 5,
endIndent: 5,
),
Expanded(
child: GridView.count(
crossAxisCount: 6,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
padding: const EdgeInsets.all(10),
children: radicalGridElements,
),
),
],
Divider(
color: AppTheme.jishoGreen.background,
thickness: 3,
height: 30,
indent: 5,
endIndent: 5,
),
Expanded(
child: GridView.count(
crossAxisCount: 6,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
padding: const EdgeInsets.all(10),
children: radicalGridElements,
),
),
],
),
),
);
}

View File

@ -1,8 +1,10 @@
import 'package:confirm_dialog/confirm_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter_settings_ui/flutter_settings_ui.dart';
import 'package:mdi/mdi.dart';
import '../bloc/theme/theme_bloc.dart';
import '../components/common/denshi_jisho_background.dart';
import '../models/history/search.dart';
import '../settings.dart';
@ -36,6 +38,32 @@ class _SettingsViewState extends State<SettingsView> {
setState(() => autoThemeEnabled = b);
}
Future<int?> Function(BuildContext) _chooseFromList({
required List<String> list,
int? chosen,
String? title,
}) =>
(context) => Navigator.push<int>(
context,
MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(title: title == null ? null : Text(title)),
body: DenshiJishoBackground(
child: ListView.builder(
itemBuilder: (context, i) => ListTile(
title: Text(list[i]),
trailing: (chosen != null && chosen == i)
? const Icon(Icons.check)
: null,
onTap: () => Navigator.pop(context, i),
),
itemCount: list.length,
),
),
),
),
);
@override
Widget build(BuildContext context) => BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, state) {
@ -44,6 +72,10 @@ class _SettingsViewState extends State<SettingsView> {
state is DarkThemeState ? AppTheme.jishoGreen.background : null,
);
const SettingsTileTheme theme = SettingsTileTheme(
horizontalTitleGap: 0,
);
return SettingsList(
backgroundColor: Colors.transparent,
contentPadding: const EdgeInsets.symmetric(vertical: 10),
@ -54,21 +86,48 @@ class _SettingsViewState extends State<SettingsView> {
tiles: <SettingsTile>[
SettingsTile.switchTile(
title: 'Use romaji',
leading: const Icon(Mdi.alphabetical),
onToggle: (b) {
setState(() => romajiEnabled = b);
},
switchValue: romajiEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
),
SettingsTile.switchTile(
title: 'Extensive search',
leading: const Icon(Icons.downloading),
onToggle: (b) {
setState(() => extensiveSearchEnabled = b);
},
switchValue: extensiveSearchEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
subtitle:
'Gathers extra data when searching for words, at the expense of having to wait for extra word details',
// subtitle:
// 'Gathers extra data when searching for words, at the expense of having to wait for extra word details.',
// subtitleWidget:
trailing: const Icon(Icons.info),
subtitleMaxLines: 3,
),
SettingsTile(
title: 'Japanese font',
leading: const Icon(Icons.format_size),
onPressed: (context) async {
final int? i = await _chooseFromList(
list: [
for (final font in JapaneseFont.values) font.name
],
chosen: japaneseFont.index,
)(context);
if (i != null)
setState(() {
japaneseFont = JapaneseFont.values[i];
});
},
theme: theme,
trailing: Text(japaneseFont.name),
// subtitle:
// 'Which font to use for japanese text. This might be useful if your phone shows kanji with a Chinese font.',
subtitleMaxLines: 3,
),
],
@ -78,13 +137,16 @@ class _SettingsViewState extends State<SettingsView> {
titleTextStyle: _titleTextStyle,
tiles: <SettingsTile>[
SettingsTile.switchTile(
title: 'Automatically determine theme',
title: 'Automatic theme',
leading: const Icon(Icons.brightness_auto),
onToggle: toggleAutoTheme,
switchValue: autoThemeEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
),
SettingsTile.switchTile(
title: 'Dark Theme',
leading: const Icon(Icons.dark_mode),
onToggle: (b) {
BlocProvider.of<ThemeBloc>(context)
.add(SetTheme(themeIsDark: b));
@ -92,6 +154,7 @@ class _SettingsViewState extends State<SettingsView> {
},
switchValue: darkThemeEnabled,
enabled: !autoThemeEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
),
],

View File

@ -1,13 +1,50 @@
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:shared_preferences/shared_preferences.dart';
final SharedPreferences _prefs = GetIt.instance.get<SharedPreferences>();
enum JapaneseFont {
none,
droidSansJapanese,
notoSansCJK,
notoSerifCJK,
}
extension Methods on JapaneseFont {
TextStyle get textStyle {
String? fontFamily;
switch (this) {
case JapaneseFont.droidSansJapanese:
fontFamily = 'Droid Sans Japanese';
break;
case JapaneseFont.notoSansCJK:
fontFamily = 'Noto Sans CJK';
break;
case JapaneseFont.notoSerifCJK:
fontFamily = 'Noto Serif CJK';
break;
case JapaneseFont.none:
}
return TextStyle(fontFamily: fontFamily);
}
String get name =>
{
JapaneseFont.none: 'Default',
JapaneseFont.droidSansJapanese: 'Droid Sans Japanese',
JapaneseFont.notoSansCJK: 'Noto Sans CJK',
JapaneseFont.notoSerifCJK: 'Noto Serif CJK',
}[this] ??
'';
}
const Map<String, dynamic> _defaults = {
'romajiEnabled': false,
'extensiveSearch': true,
'darkThemeEnabled': false,
'autoThemeEnabled': false,
'japaneseFont': JapaneseFont.droidSansJapanese,
};
bool _getSettingOrDefault(String settingName) =>
@ -17,8 +54,13 @@ bool get romajiEnabled => _getSettingOrDefault('romajiEnabled');
bool get extensiveSearchEnabled => _getSettingOrDefault('extensiveSearch');
bool get darkThemeEnabled => _getSettingOrDefault('darkThemeEnabled');
bool get autoThemeEnabled => _getSettingOrDefault('autoThemeEnabled');
JapaneseFont get japaneseFont {
final int? i = _prefs.getInt('japaneseFont');
return (i != null) ? JapaneseFont.values[i] : _defaults['japaneseFont'];
}
set romajiEnabled(b) => _prefs.setBool('romajiEnabled', b);
set extensiveSearchEnabled(b) => _prefs.setBool('extensiveSearch', b);
set darkThemeEnabled(b) => _prefs.setBool('darkThemeEnabled', b);
set autoThemeEnabled(b) => _prefs.setBool('autoThemeEnabled', b);
set japaneseFont(JapaneseFont jf) => _prefs.setInt('japaneseFont', jf.index);

View File

@ -44,18 +44,27 @@ flutter:
uses-material-design: true
assets:
- assets/fonts/
- assets/images/
- assets/images/logo/
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
fonts:
- family: Droid Sans Japanese
fonts:
- asset: assets/fonts/DroidSansJapanese.ttf
- family: Noto Sans CJK
fonts:
- asset: assets/fonts/NotoSansCJK-Regular.ttc
- family: Noto Serif CJK
fonts:
- asset: assets/fonts/NotoSerifCJK-Regular.ttc
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf