info: color palette

This commit is contained in:
Thibault Deckers 2024-04-28 16:43:16 +02:00
parent fc9d282caa
commit 5b2fbe48d3
4 changed files with 98 additions and 5 deletions

View file

@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Cataloguing: identify Apple variant of HDR images - Cataloguing: identify Apple variant of HDR images
- Collection: allow using hash (md5/sha1/sha256) when bulk renaming - Collection: allow using hash (md5/sha1/sha256) when bulk renaming
- Info: color palette
- option to force using western arabic numerals for dates - option to force using western arabic numerals for dates
### Changed ### Changed

View file

@ -47,6 +47,7 @@ class AIcons {
static const mainStorage = Icons.smartphone_outlined; static const mainStorage = Icons.smartphone_outlined;
static const mimeType = Icons.code_outlined; static const mimeType = Icons.code_outlined;
static const opacity = Icons.opacity; static const opacity = Icons.opacity;
static const palette = Icons.palette_outlined;
static final privacy = MdiIcons.shieldAccountOutline; static final privacy = MdiIcons.shieldAccountOutline;
static const rating = Icons.star_border_outlined; static const rating = Icons.star_border_outlined;
static const ratingFull = Icons.star; static const ratingFull = Icons.star;

View file

@ -0,0 +1,87 @@
import 'dart:async';
import 'dart:math';
import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/entry/extensions/images.dart';
import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/color_indicator.dart';
import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flex_color_picker/flex_color_picker.dart' as flex;
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:palette_generator/palette_generator.dart';
import 'package:provider/provider.dart';
class ColorSectionSliver extends StatefulWidget {
final AvesEntry entry;
const ColorSectionSliver({super.key, required this.entry});
@override
State<ColorSectionSliver> createState() => _ColorSectionSliverState();
}
class _ColorSectionSliverState extends State<ColorSectionSliver> {
late final Future<PaletteGenerator> _paletteLoader;
@override
void initState() {
super.initState();
final provider = widget.entry.getThumbnail(extent: min(200, widget.entry.displaySize.longestSide));
_paletteLoader = PaletteGenerator.fromImageProvider(
provider,
maximumColorCount: 10,
// do not use the default palette filter
filters: [],
);
}
@override
Widget build(BuildContext context) {
return SliverToBoxAdapter(
child: FutureBuilder<PaletteGenerator>(
future: _paletteLoader,
builder: (context, snapshot) {
final colors = snapshot.data?.paletteColors;
if (colors == null || colors.isEmpty) return const SizedBox();
final durations = context.watch<DurationsData>();
return Wrap(
alignment: WrapAlignment.center,
children: AnimationConfiguration.toStaggeredList(
duration: durations.staggeredAnimation,
delay: durations.staggeredAnimationDelay * timeDilation,
childAnimationBuilder: (child) => SlideAnimation(
verticalOffset: 50.0,
child: FadeInAnimation(
child: child,
),
),
children: [
const SectionRow(icon: AIcons.palette),
...colors.map(
(v) => Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
ColorIndicator(value: v.color),
const SizedBox(width: 8),
SelectableText(
'#${v.color.hex}',
style: const TextStyle(fontFamily: 'monospace'),
),
],
),
),
),
],
),
);
},
),
);
}
}

View file

@ -17,6 +17,7 @@ import 'package:aves/widgets/viewer/info/basic_section.dart';
import 'package:aves/widgets/viewer/info/embedded/embedded_data_opener.dart'; import 'package:aves/widgets/viewer/info/embedded/embedded_data_opener.dart';
import 'package:aves/widgets/viewer/info/info_app_bar.dart'; import 'package:aves/widgets/viewer/info/info_app_bar.dart';
import 'package:aves/widgets/viewer/info/location_section.dart'; import 'package:aves/widgets/viewer/info/location_section.dart';
import 'package:aves/widgets/viewer/info/color_section.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_dir.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_dir.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_section.dart';
import 'package:aves/widgets/viewer/multipage/conductor.dart'; import 'package:aves/widgets/viewer/multipage/conductor.dart';
@ -233,10 +234,6 @@ class _InfoPageContentState extends State<_InfoPageContent> {
], ],
), ),
); );
final metadataSliver = MetadataSectionSliver(
entry: entry,
metadataNotifier: _metadataNotifier,
);
return NotificationListener<FilterNotification>( return NotificationListener<FilterNotification>(
onNotification: (notification) { onNotification: (notification) {
@ -262,7 +259,14 @@ class _InfoPageContentState extends State<_InfoPageContent> {
), ),
SliverPadding( SliverPadding(
padding: horizontalPadding + const EdgeInsets.only(bottom: 8), padding: horizontalPadding + const EdgeInsets.only(bottom: 8),
sliver: metadataSliver, sliver: MetadataSectionSliver(
entry: entry,
metadataNotifier: _metadataNotifier,
),
),
SliverPadding(
padding: horizontalPadding + const EdgeInsets.only(bottom: 8),
sliver: ColorSectionSliver(entry: entry),
), ),
const BottomPaddingSliver(), const BottomPaddingSliver(),
], ],