improved icon display

This commit is contained in:
Thibault Deckers 2020-09-20 22:51:01 +09:00
parent acf26677af
commit a44f16087a
14 changed files with 59 additions and 33 deletions

View file

@ -41,8 +41,14 @@ class AlbumFilter extends CollectionFilter {
String get tooltip => album; String get tooltip => album;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true, bool embossed = false}) {
return IconUtils.getAlbumIcon(context: context, album: album, size: size) ?? (showGenericIcon ? Icon(AIcons.album, size: size) : null); return IconUtils.getAlbumIcon(
context: context,
album: album,
size: size,
embossed: embossed,
) ??
(showGenericIcon ? Icon(AIcons.album, size: size) : null);
} }
@override @override

View file

@ -19,7 +19,7 @@ class FavouriteFilter extends CollectionFilter {
String get label => 'Favourite'; String get label => 'Favourite';
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.favourite, size: size); Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true, bool embossed = false}) => Icon(AIcons.favourite, size: size);
@override @override
String get typeKey => type; String get typeKey => type;

View file

@ -57,7 +57,7 @@ abstract class CollectionFilter implements Comparable<CollectionFilter> {
String get tooltip => label; String get tooltip => label;
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}); Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true, bool embossed = false});
Future<Color> color(BuildContext context) => SynchronousFuture(stringToColor(label)); Future<Color> color(BuildContext context) => SynchronousFuture(stringToColor(label));

View file

@ -39,9 +39,11 @@ class LocationFilter extends CollectionFilter {
String get label => _location; String get label => _location;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true, bool embossed = false}) {
final flag = countryCodeToFlag(_countryCode); final flag = countryCodeToFlag(_countryCode);
if (flag != null) return Text(flag, style: TextStyle(fontSize: size)); // as of Flutter v1.22.0-12.1.pre emoji shadows are rendered as colorful duplicates,
// not filled with the shadow color as expected, so we remove them
if (flag != null) return Text(flag, style: TextStyle(fontSize: size, shadows: []));
return Icon(AIcons.location, size: size); return Icon(AIcons.location, size: size);
} }

View file

@ -60,7 +60,7 @@ class MimeFilter extends CollectionFilter {
String get label => _label; String get label => _label;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size); Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true, bool embossed = false}) => Icon(_icon, size: size);
@override @override
String get typeKey => type; String get typeKey => type;

View file

@ -53,7 +53,7 @@ class QueryFilter extends CollectionFilter {
String get label => '$query'; String get label => '$query';
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.text, size: size); Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true, bool embossed = false}) => Icon(AIcons.text, size: size);
@override @override
Future<Color> color(BuildContext context) => colorful ? super.color(context) : SynchronousFuture(Colors.white); Future<Color> color(BuildContext context) => colorful ? super.color(context) : SynchronousFuture(Colors.white);

View file

@ -31,7 +31,7 @@ class TagFilter extends CollectionFilter {
String get label => tag; String get label => tag;
@override @override
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => showGenericIcon ? Icon(AIcons.tag, size: size) : null; Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true, bool embossed = false}) => showGenericIcon ? Icon(AIcons.tag, size: size) : null;
@override @override
String get typeKey => type; String get typeKey => type;

View file

@ -12,6 +12,11 @@ class Constants {
fontFamily: 'Concourse Caps', fontFamily: 'Concourse Caps',
); );
static const embossShadow = Shadow(
color: Colors.black87,
offset: Offset(0.5, 1.0),
);
static const List<Dependency> androidDependencies = [ static const List<Dependency> androidDependencies = [
Dependency( Dependency(
name: 'CWAC-Document', name: 'CWAC-Document',
@ -58,6 +63,12 @@ class Constants {
licenseUrl: 'https://github.com/dart-lang/collection/blob/master/LICENSE', licenseUrl: 'https://github.com/dart-lang/collection/blob/master/LICENSE',
sourceUrl: 'https://github.com/dart-lang/collection', sourceUrl: 'https://github.com/dart-lang/collection',
), ),
Dependency(
name: 'Decorated Icon',
license: 'MIT',
licenseUrl: 'https://github.com/benPesso/flutter_decorated_icon/blob/master/LICENSE',
sourceUrl: 'https://github.com/benPesso/flutter_decorated_icon',
),
Dependency( Dependency(
name: 'Draggable Scrollbar', name: 'Draggable Scrollbar',
license: 'MIT', license: 'MIT',

View file

@ -1,4 +1,5 @@
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/icons.dart'; import 'package:aves/widgets/common/icons.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -79,7 +80,7 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final hasBackground = widget.background != null; final hasBackground = widget.background != null;
final leading = filter.iconBuilder(context, AvesFilterChip.iconSize, showGenericIcon: widget.showGenericIcon); final leading = filter.iconBuilder(context, AvesFilterChip.iconSize, showGenericIcon: widget.showGenericIcon, embossed: hasBackground);
final trailing = widget.removable ? Icon(AIcons.clear, size: AvesFilterChip.iconSize) : null; final trailing = widget.removable ? Icon(AIcons.clear, size: AvesFilterChip.iconSize) : null;
Widget content = Row( Widget content = Row(
@ -126,12 +127,7 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
color: Colors.black54, color: Colors.black54,
child: DefaultTextStyle( child: DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2.copyWith( style: Theme.of(context).textTheme.bodyText2.copyWith(
shadows: [ shadows: [Constants.embossShadow],
Shadow(
color: Colors.black87,
offset: Offset(0.5, 1.0),
)
],
), ),
child: content, child: content,
), ),

View file

@ -2,7 +2,9 @@ import 'dart:ui';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/image_providers/app_icon_image_provider.dart'; import 'package:aves/widgets/common/image_providers/app_icon_image_provider.dart';
import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AIcons { class AIcons {
@ -162,15 +164,17 @@ class IconUtils {
@required BuildContext context, @required BuildContext context,
@required String album, @required String album,
double size = 24, double size = 24,
bool embossed = false,
}) { }) {
Widget buildIcon(IconData icon) => embossed ? DecoratedIcon(icon, shadows: [Constants.embossShadow], size: size) : Icon(icon, size: size);
switch (androidFileUtils.getAlbumType(album)) { switch (androidFileUtils.getAlbumType(album)) {
case AlbumType.camera: case AlbumType.camera:
return Icon(AIcons.cameraAlbum, size: size); return buildIcon(AIcons.cameraAlbum);
case AlbumType.screenshots: case AlbumType.screenshots:
case AlbumType.screenRecordings: case AlbumType.screenRecordings:
return Icon(AIcons.screenshotAlbum, size: size); return buildIcon(AIcons.screenshotAlbum);
case AlbumType.download: case AlbumType.download:
return Icon(AIcons.downloadAlbum, size: size); return buildIcon(AIcons.downloadAlbum);
case AlbumType.app: case AlbumType.app:
return Image( return Image(
image: AppIconImage( image: AppIconImage(

View file

@ -5,11 +5,13 @@ import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/collection/thumbnail/raster.dart'; import 'package:aves/widgets/collection/thumbnail/raster.dart';
import 'package:aves/widgets/collection/thumbnail/vector.dart'; import 'package:aves/widgets/collection/thumbnail/vector.dart';
import 'package:aves/widgets/common/aves_filter_chip.dart'; import 'package:aves/widgets/common/aves_filter_chip.dart';
import 'package:aves/widgets/common/icons.dart'; import 'package:aves/widgets/common/icons.dart';
import 'package:aves/widgets/filter_grids/common/filter_grid_page.dart'; import 'package:aves/widgets/filter_grids/common/filter_grid_page.dart';
import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DecoratedFilterChip extends StatelessWidget { class DecoratedFilterChip extends StatelessWidget {
@ -65,19 +67,21 @@ class DecoratedFilterChip extends StatelessWidget {
if (pinned) if (pinned)
Padding( Padding(
padding: EdgeInsets.only(right: 8), padding: EdgeInsets.only(right: 8),
child: Icon( child: DecoratedIcon(
AIcons.pin, AIcons.pin,
size: 16,
color: FilterGridPage.detailColor, color: FilterGridPage.detailColor,
shadows: [Constants.embossShadow],
size: 16,
), ),
), ),
if (filter is AlbumFilter && androidFileUtils.isOnRemovableStorage(filter.album)) if (filter is AlbumFilter && androidFileUtils.isOnRemovableStorage(filter.album))
Padding( Padding(
padding: EdgeInsets.only(right: 8), padding: EdgeInsets.only(right: 8),
child: Icon( child: DecoratedIcon(
AIcons.removableStorage, AIcons.removableStorage,
size: 16,
color: FilterGridPage.detailColor, color: FilterGridPage.detailColor,
shadows: [Constants.embossShadow],
size: 16,
), ),
), ),
count, count,

View file

@ -1,5 +1,4 @@
import 'dart:math'; import 'dart:math';
import 'dart:ui';
import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_entry.dart';
import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/image_metadata.dart';
@ -10,6 +9,7 @@ import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/common/icons.dart'; import 'package:aves/widgets/common/icons.dart';
import 'package:aves/widgets/fullscreen/overlay/common.dart'; import 'package:aves/widgets/fullscreen/overlay/common.dart';
import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -135,12 +135,7 @@ class _FullscreenBottomOverlayContent extends AnimatedWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DefaultTextStyle( return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2.copyWith( style: Theme.of(context).textTheme.bodyText2.copyWith(
shadows: [ shadows: [Constants.embossShadow],
Shadow(
color: Colors.black87,
offset: Offset(0.5, 1.0),
)
],
), ),
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
@ -217,7 +212,7 @@ class _LocationRow extends AnimatedWidget {
} }
return Row( return Row(
children: [ children: [
Icon(AIcons.location, size: _iconSize), DecoratedIcon(AIcons.location, shadows: [Constants.embossShadow], size: _iconSize),
SizedBox(width: _iconPadding), SizedBox(width: _iconPadding),
Expanded(child: Text(location, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(location, strutStyle: Constants.overflowStrutStyle)),
], ],
@ -237,7 +232,7 @@ class _DateRow extends StatelessWidget {
final resolution = '${entry.width ?? '?'} × ${entry.height ?? '?'}'; final resolution = '${entry.width ?? '?'} × ${entry.height ?? '?'}';
return Row( return Row(
children: [ children: [
Icon(AIcons.date, size: _iconSize), DecoratedIcon(AIcons.date, shadows: [Constants.embossShadow], size: _iconSize),
SizedBox(width: _iconPadding), SizedBox(width: _iconPadding),
Expanded(flex: 3, child: Text(dateText, strutStyle: Constants.overflowStrutStyle)), Expanded(flex: 3, child: Text(dateText, strutStyle: Constants.overflowStrutStyle)),
if (!entry.isSvg) Expanded(flex: 2, child: Text(resolution, strutStyle: Constants.overflowStrutStyle)), if (!entry.isSvg) Expanded(flex: 2, child: Text(resolution, strutStyle: Constants.overflowStrutStyle)),
@ -255,7 +250,7 @@ class _ShootingRow extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
children: [ children: [
Icon(AIcons.shooting, size: _iconSize), DecoratedIcon(AIcons.shooting, shadows: [Constants.embossShadow], size: _iconSize),
SizedBox(width: _iconPadding), SizedBox(width: _iconPadding),
Expanded(child: Text(details.aperture, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(details.aperture, strutStyle: Constants.overflowStrutStyle)),
Expanded(child: Text(details.exposureTime, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(details.exposureTime, strutStyle: Constants.overflowStrutStyle)),

View file

@ -141,6 +141,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.5" version: "2.1.5"
decorated_icon:
dependency: "direct main"
description:
name: decorated_icon
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
draggable_scrollbar: draggable_scrollbar:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -38,6 +38,7 @@ dependencies:
sdk: flutter sdk: flutter
charts_flutter: charts_flutter:
collection: collection:
decorated_icon:
draggable_scrollbar: draggable_scrollbar:
# path: ../flutter-draggable-scrollbar # path: ../flutter-draggable-scrollbar
git: git: