diff --git a/lib/components/fit_text.dart b/lib/components/fit_text.dart new file mode 100644 index 0000000..ec7466e --- /dev/null +++ b/lib/components/fit_text.dart @@ -0,0 +1,61 @@ +import "package:flutter/material.dart"; + +class FitText extends StatefulWidget { + const FitText({ + Key? key, + required this.texts, + this.style, + this.separator = " ", + }) : super(key: key); + final List<(String, int)> texts; + final TextStyle? style; + final String separator; + + @override + State createState() => _FitText(); +} + +class _FitText extends State { + late List texts; + late List sizes; + + Size _textSize(String text, TextStyle? style) { + final TextPainter textPainter = TextPainter( + text: TextSpan(text: text, style: style), + maxLines: 1, + textDirection: TextDirection.ltr) + ..layout(minWidth: 0, maxWidth: double.infinity); + return textPainter.size; + } + + @override + void initState() { + super.initState(); + final tmp = widget.texts.map((e) => e.$2).toSet().toList() + ..sort((b, a) => a.compareTo(b)); + sizes = []; + texts = []; + for (final i in tmp) { + final text = widget.texts + .where((e) => e.$2 >= i) + .map((e) => e.$1) + .join(widget.separator); + texts.add(text); + sizes.add(_textSize(text, widget.style).width); + } + } + + @override + Widget build(BuildContext context) { + if (texts.isEmpty) return Container(); + return LayoutBuilder(builder: (context, constraints) { + final double maxWidth = constraints.maxWidth; + for (int i = sizes.length - 1; i >= 0; i--) { + if (sizes[i] <= maxWidth) { + return Text(texts[i], style: widget.style); + } + } + return Text(texts[0], style: widget.style); + }); + } +} diff --git a/lib/viewer/single.dart b/lib/viewer/single.dart index 9e80d60..551fc6e 100644 --- a/lib/viewer/single.dart +++ b/lib/viewer/single.dart @@ -12,6 +12,7 @@ import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import '../api/file.dart'; import '../api/gallery.dart'; +import '../components/fit_text.dart'; import '../globals.dart'; final _log = Logger("SinglePageViewer"); @@ -191,6 +192,7 @@ class _SinglePageViewer extends State Widget _buildTopAppBar(BuildContext context) { if (!_showMenu) return Container(); + final theme = Theme.of(context); return Positioned( top: 0, left: 0, @@ -201,8 +203,14 @@ class _SinglePageViewer extends State context.canPop() ? context.pop() : context.go(_back); }, icon: const Icon(Icons.close)), - title: - Text("${_data!.meta.preferredTitle} - ${_pages![_index].name}"), + title: FitText( + texts: [ + (_data!.meta.preferredTitle, 0), + (_pages![_index].name, 1) + ], + style: theme.appBarTheme.titleTextStyle ?? + theme.textTheme.titleLarge, + separator: " - "), actions: [ buildThemeModeIcon(context), buildMoreVertSettingsButon(context),