info: color palette
This commit is contained in:
parent
fc9d282caa
commit
5b2fbe48d3
4 changed files with 98 additions and 5 deletions
|
@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
- Cataloguing: identify Apple variant of HDR images
|
||||
- Collection: allow using hash (md5/sha1/sha256) when bulk renaming
|
||||
- Info: color palette
|
||||
- option to force using western arabic numerals for dates
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -47,6 +47,7 @@ class AIcons {
|
|||
static const mainStorage = Icons.smartphone_outlined;
|
||||
static const mimeType = Icons.code_outlined;
|
||||
static const opacity = Icons.opacity;
|
||||
static const palette = Icons.palette_outlined;
|
||||
static final privacy = MdiIcons.shieldAccountOutline;
|
||||
static const rating = Icons.star_border_outlined;
|
||||
static const ratingFull = Icons.star;
|
||||
|
|
87
lib/widgets/viewer/info/color_section.dart
Normal file
87
lib/widgets/viewer/info/color_section.dart
Normal 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'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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/info_app_bar.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_section.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>(
|
||||
onNotification: (notification) {
|
||||
|
@ -262,7 +259,14 @@ class _InfoPageContentState extends State<_InfoPageContent> {
|
|||
),
|
||||
SliverPadding(
|
||||
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(),
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue