#706 viewer: histogram
This commit is contained in:
parent
99dd7ec0ff
commit
05d4d01ef7
27 changed files with 651 additions and 143 deletions
|
@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Video: improved seek accuracy, HDR support, AV1 support, playback speed from x0.25 to x4
|
- Video: improved seek accuracy, HDR support, AV1 support, playback speed from x0.25 to x4
|
||||||
- support for animated AVIF (requires rescan)
|
- support for animated AVIF (requires rescan)
|
||||||
- Collection: filtering by rating range
|
- Collection: filtering by rating range
|
||||||
|
- Viewer: optionally show histogram on overlay
|
||||||
- About: data usage
|
- About: data usage
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -233,6 +233,10 @@
|
||||||
"nameConflictStrategyReplace": "Replace",
|
"nameConflictStrategyReplace": "Replace",
|
||||||
"nameConflictStrategySkip": "Skip",
|
"nameConflictStrategySkip": "Skip",
|
||||||
|
|
||||||
|
"overlayHistogramNone": "None",
|
||||||
|
"overlayHistogramRGB": "RGB",
|
||||||
|
"overlayHistogramLuminance": "Luminance",
|
||||||
|
|
||||||
"subtitlePositionTop": "Top",
|
"subtitlePositionTop": "Top",
|
||||||
"subtitlePositionBottom": "Bottom",
|
"subtitlePositionBottom": "Bottom",
|
||||||
|
|
||||||
|
@ -809,6 +813,7 @@
|
||||||
"settingsViewerOverlayTile": "Overlay",
|
"settingsViewerOverlayTile": "Overlay",
|
||||||
"settingsViewerOverlayPageTitle": "Overlay",
|
"settingsViewerOverlayPageTitle": "Overlay",
|
||||||
"settingsViewerShowOverlayOnOpening": "Show on opening",
|
"settingsViewerShowOverlayOnOpening": "Show on opening",
|
||||||
|
"settingsViewerShowHistogram": "Show histogram",
|
||||||
"settingsViewerShowMinimap": "Show minimap",
|
"settingsViewerShowMinimap": "Show minimap",
|
||||||
"settingsViewerShowInformation": "Show information",
|
"settingsViewerShowInformation": "Show information",
|
||||||
"settingsViewerShowInformationSubtitle": "Show title, date, location, etc.",
|
"settingsViewerShowInformationSubtitle": "Show title, date, location, etc.",
|
||||||
|
|
|
@ -72,6 +72,7 @@ class SettingsDefaults {
|
||||||
];
|
];
|
||||||
static const showOverlayOnOpening = true;
|
static const showOverlayOnOpening = true;
|
||||||
static const showOverlayMinimap = false;
|
static const showOverlayMinimap = false;
|
||||||
|
static const overlayHistogramStyle = OverlayHistogramStyle.none;
|
||||||
static const showOverlayInfo = true;
|
static const showOverlayInfo = true;
|
||||||
static const showOverlayDescription = false;
|
static const showOverlayDescription = false;
|
||||||
static const showOverlayRatingTags = false;
|
static const showOverlayRatingTags = false;
|
||||||
|
|
|
@ -14,6 +14,10 @@ mixin ViewerSettings on SettingsAccess {
|
||||||
|
|
||||||
set showOverlayMinimap(bool newValue) => set(SettingKeys.showOverlayMinimapKey, newValue);
|
set showOverlayMinimap(bool newValue) => set(SettingKeys.showOverlayMinimapKey, newValue);
|
||||||
|
|
||||||
|
OverlayHistogramStyle get overlayHistogramStyle => getEnumOrDefault(SettingKeys.overlayHistogramStyleKey, SettingsDefaults.overlayHistogramStyle, OverlayHistogramStyle.values);
|
||||||
|
|
||||||
|
set overlayHistogramStyle(OverlayHistogramStyle newValue) => set(SettingKeys.overlayHistogramStyleKey, newValue.toString());
|
||||||
|
|
||||||
bool get showOverlayInfo => getBool(SettingKeys.showOverlayInfoKey) ?? SettingsDefaults.showOverlayInfo;
|
bool get showOverlayInfo => getBool(SettingKeys.showOverlayInfoKey) ?? SettingsDefaults.showOverlayInfo;
|
||||||
|
|
||||||
set showOverlayInfo(bool newValue) => set(SettingKeys.showOverlayInfoKey, newValue);
|
set showOverlayInfo(bool newValue) => set(SettingKeys.showOverlayInfoKey, newValue);
|
||||||
|
|
|
@ -151,6 +151,19 @@ extension ExtraSlideshowVideoPlaybackView on SlideshowVideoPlayback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension ExtraOverlayHistogramStyleView on OverlayHistogramStyle {
|
||||||
|
String getName(BuildContext context) {
|
||||||
|
switch (this) {
|
||||||
|
case OverlayHistogramStyle.none:
|
||||||
|
return context.l10n.overlayHistogramNone;
|
||||||
|
case OverlayHistogramStyle.rgb:
|
||||||
|
return context.l10n.overlayHistogramRGB;
|
||||||
|
case OverlayHistogramStyle.luminance:
|
||||||
|
return context.l10n.overlayHistogramLuminance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension ExtraSubtitlePositionView on SubtitlePosition {
|
extension ExtraSubtitlePositionView on SubtitlePosition {
|
||||||
String getName(BuildContext context) {
|
String getName(BuildContext context) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
import 'package:aves/view/view.dart';
|
||||||
import 'package:aves/widgets/common/basic/scaffold.dart';
|
import 'package:aves/widgets/common/basic/scaffold.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/settings/common/tiles.dart';
|
import 'package:aves/widgets/settings/common/tiles.dart';
|
||||||
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
@ -82,6 +84,14 @@ class ViewerOverlayPage extends StatelessWidget {
|
||||||
onChanged: (v) => settings.showOverlayThumbnailPreview = v,
|
onChanged: (v) => settings.showOverlayThumbnailPreview = v,
|
||||||
title: context.l10n.settingsViewerShowOverlayThumbnails,
|
title: context.l10n.settingsViewerShowOverlayThumbnails,
|
||||||
),
|
),
|
||||||
|
if (!useTvLayout)
|
||||||
|
SettingsSelectionListTile<OverlayHistogramStyle>(
|
||||||
|
values: OverlayHistogramStyle.values,
|
||||||
|
getName: (context, v) => v.getName(context),
|
||||||
|
selector: (context, s) => s.overlayHistogramStyle,
|
||||||
|
onSelection: (v) => settings.overlayHistogramStyle = v,
|
||||||
|
tileTitle: context.l10n.settingsViewerShowHistogram,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -108,3 +108,11 @@ class EntryMovedNotification extends Notification with EquatableMixin {
|
||||||
|
|
||||||
const EntryMovedNotification(this.moveType, this.entries);
|
const EntryMovedNotification(this.moveType, this.entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class FullImageLoadedNotification extends Notification {
|
||||||
|
final AvesEntry entry;
|
||||||
|
final ImageProvider image;
|
||||||
|
|
||||||
|
const FullImageLoadedNotification(this.entry, this.image);
|
||||||
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ import 'package:aves/widgets/viewer/overlay/top.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/video/video.dart';
|
import 'package:aves/widgets/viewer/overlay/video/video.dart';
|
||||||
import 'package:aves/widgets/viewer/page_entry_builder.dart';
|
import 'package:aves/widgets/viewer/page_entry_builder.dart';
|
||||||
import 'package:aves/widgets/viewer/video/conductor.dart';
|
import 'package:aves/widgets/viewer/video/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/conductor.dart';
|
import 'package:aves/widgets/viewer/view/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/controller_mixin.dart';
|
import 'package:aves/widgets/viewer/visual/controller_mixin.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:aves_utils/aves_utils.dart';
|
import 'package:aves_utils/aves_utils.dart';
|
||||||
|
@ -512,6 +512,10 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
||||||
bool _handleNotification(dynamic notification) {
|
bool _handleNotification(dynamic notification) {
|
||||||
if (notification is FilterSelectedNotification) {
|
if (notification is FilterSelectedNotification) {
|
||||||
_goToCollection(notification.filter);
|
_goToCollection(notification.filter);
|
||||||
|
} else if (notification is FullImageLoadedNotification) {
|
||||||
|
final viewStateController = context.read<ViewStateConductor>().getOrCreateController(notification.entry);
|
||||||
|
// microtask so that listeners do not trigger during build
|
||||||
|
scheduleMicrotask(() => viewStateController.fullImageNotifier.value = notification.image);
|
||||||
} else if (notification is EntryDeletedNotification) {
|
} else if (notification is EntryDeletedNotification) {
|
||||||
_onEntryRemoved(context, notification.entries);
|
_onEntryRemoved(context, notification.entries);
|
||||||
} else if (notification is EntryMovedNotification) {
|
} else if (notification is EntryMovedNotification) {
|
||||||
|
|
202
lib/widgets/viewer/overlay/histogram.dart
Normal file
202
lib/widgets/viewer/overlay/histogram.dart
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:aves/model/entry/entry.dart';
|
||||||
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/top.dart';
|
||||||
|
import 'package:aves_model/aves_model.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ImageHistogram extends StatefulWidget {
|
||||||
|
final AvesEntry entry;
|
||||||
|
final ImageProvider image;
|
||||||
|
|
||||||
|
const ImageHistogram({
|
||||||
|
super.key,
|
||||||
|
required this.entry,
|
||||||
|
required this.image,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ImageHistogram> createState() => _ImageHistogramState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ImageHistogramState extends State<ImageHistogram> {
|
||||||
|
Map<Color, List<double>> _levels = {};
|
||||||
|
ImageStream? _imageStream;
|
||||||
|
late ImageStreamListener _imageListener;
|
||||||
|
|
||||||
|
ImageProvider get imageProvider => widget.image;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_registerWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant ImageHistogram oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
_unregisterWidget(oldWidget);
|
||||||
|
_registerWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_unregisterWidget(widget);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _registerWidget(ImageHistogram widget) {
|
||||||
|
_imageStream = imageProvider.resolve(ImageConfiguration.empty);
|
||||||
|
_imageListener = ImageStreamListener((image, synchronousCall) {
|
||||||
|
_updateLevels(image);
|
||||||
|
});
|
||||||
|
_imageStream?.addListener(_imageListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _unregisterWidget(ImageHistogram widget) {
|
||||||
|
_imageStream?.removeListener(_imageListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return IgnorePointer(
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: _HistogramPainter(
|
||||||
|
levels: _levels,
|
||||||
|
borderColor: ViewerTopOverlay.componentBorderColor,
|
||||||
|
),
|
||||||
|
size: const Size(ViewerTopOverlay.componentDimension, ViewerTopOverlay.componentDimension * .6),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int bins = 256;
|
||||||
|
static const int normMax = bins - 1;
|
||||||
|
|
||||||
|
Future<void> _updateLevels(ImageInfo info) async {
|
||||||
|
final image = info.image;
|
||||||
|
final data = (await image.toByteData(format: ImageByteFormat.rawExtendedRgba128))!;
|
||||||
|
final floats = Float32List.view(data.buffer);
|
||||||
|
|
||||||
|
final newLevels = switch (settings.overlayHistogramStyle) {
|
||||||
|
OverlayHistogramStyle.rgb => _computeRgbLevels(floats),
|
||||||
|
OverlayHistogramStyle.luminance => _computeLuminanceLevels(floats),
|
||||||
|
_ => <Color, List<double>>{},
|
||||||
|
};
|
||||||
|
|
||||||
|
setState(() => _levels = newLevels);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Color, List<double>> _computeRgbLevels(Float32List floats) {
|
||||||
|
final redLevels = List.filled(bins, 0);
|
||||||
|
final greenLevels = List.filled(bins, 0);
|
||||||
|
final blueLevels = List.filled(bins, 0);
|
||||||
|
|
||||||
|
final pixelCount = floats.length / 4;
|
||||||
|
for (var i = 0; i < pixelCount; i += 4) {
|
||||||
|
final a = floats[i + 3];
|
||||||
|
if (a > 0) {
|
||||||
|
final r = floats[i + 0];
|
||||||
|
final g = floats[i + 1];
|
||||||
|
final b = floats[i + 2];
|
||||||
|
redLevels[(r * normMax).round()]++;
|
||||||
|
greenLevels[(g * normMax).round()]++;
|
||||||
|
blueLevels[(b * normMax).round()]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final max = [
|
||||||
|
redLevels.max,
|
||||||
|
greenLevels.max,
|
||||||
|
blueLevels.max,
|
||||||
|
].max;
|
||||||
|
if (max == 0) return {};
|
||||||
|
|
||||||
|
final f = 1.0 / max;
|
||||||
|
return {
|
||||||
|
Colors.red: redLevels.map((v) => v * f).toList(),
|
||||||
|
Colors.green: greenLevels.map((v) => v * f).toList(),
|
||||||
|
Colors.blue: blueLevels.map((v) => v * f).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Color, List<double>> _computeLuminanceLevels(Float32List floats) {
|
||||||
|
final lumLevels = List.filled(bins, 0);
|
||||||
|
|
||||||
|
final pixelCount = floats.length / 4;
|
||||||
|
for (var i = 0; i < pixelCount; i += 4) {
|
||||||
|
final a = floats[i + 3];
|
||||||
|
if (a > 0) {
|
||||||
|
final r = floats[i + 0];
|
||||||
|
final g = floats[i + 1];
|
||||||
|
final b = floats[i + 2];
|
||||||
|
final c = Color.fromARGB((a * 255).round(), (r * 255).round(), (g * 255).round(), (b * 255).round());
|
||||||
|
lumLevels[(c.computeLuminance() * normMax).round()]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final max = lumLevels.max;
|
||||||
|
if (max == 0) return {};
|
||||||
|
|
||||||
|
final f = 1.0 / max;
|
||||||
|
return {
|
||||||
|
Colors.white: lumLevels.map((v) => v * f).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HistogramPainter extends CustomPainter {
|
||||||
|
final Map<Color, List<double>> levels;
|
||||||
|
final Color borderColor;
|
||||||
|
|
||||||
|
late final Paint fill, borderStroke;
|
||||||
|
|
||||||
|
_HistogramPainter({
|
||||||
|
required this.levels,
|
||||||
|
this.borderColor = Colors.white,
|
||||||
|
}) {
|
||||||
|
fill = Paint()
|
||||||
|
..style = PaintingStyle.fill
|
||||||
|
..color = const Color(0x33000000);
|
||||||
|
borderStroke = Paint()
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..color = borderColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final backgroundRect = Rect.fromPoints(Offset.zero, Offset(size.width, size.height));
|
||||||
|
canvas.drawRect(backgroundRect, fill);
|
||||||
|
levels.forEach((color, values) => _drawLevels(canvas, size, color, values));
|
||||||
|
canvas.drawRect(backgroundRect, borderStroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _drawLevels(Canvas canvas, Size size, Color color, List<double> values) {
|
||||||
|
if (values.length < 2) return;
|
||||||
|
|
||||||
|
final xFactor = size.width / (values.length - 1);
|
||||||
|
final yFactor = size.height;
|
||||||
|
|
||||||
|
final polyline = values.mapIndexed((i, v) => Offset(i * xFactor, size.height - v * yFactor)).toList();
|
||||||
|
canvas.drawPoints(
|
||||||
|
PointMode.polygon,
|
||||||
|
polyline,
|
||||||
|
Paint()
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..color = color);
|
||||||
|
|
||||||
|
polyline.add(Offset(size.width, size.height));
|
||||||
|
polyline.add(Offset(0, size.height));
|
||||||
|
canvas.drawPath(
|
||||||
|
Path()..addPolygon(polyline, true),
|
||||||
|
Paint()
|
||||||
|
..style = PaintingStyle.fill
|
||||||
|
..color = color.withOpacity(.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import 'dart:math';
|
||||||
import 'package:aves/model/view_state.dart';
|
import 'package:aves/model/view_state.dart';
|
||||||
import 'package:aves/widgets/editor/transform/controller.dart';
|
import 'package:aves/widgets/editor/transform/controller.dart';
|
||||||
import 'package:aves/widgets/editor/transform/transformation.dart';
|
import 'package:aves/widgets/editor/transform/transformation.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/top.dart';
|
||||||
import 'package:aves_utils/aves_utils.dart';
|
import 'package:aves_utils/aves_utils.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -11,8 +12,6 @@ import 'package:provider/provider.dart';
|
||||||
class Minimap extends StatelessWidget {
|
class Minimap extends StatelessWidget {
|
||||||
final ValueNotifier<ViewState> viewStateNotifier;
|
final ValueNotifier<ViewState> viewStateNotifier;
|
||||||
|
|
||||||
static const Size minimapSize = Size(96, 96);
|
|
||||||
|
|
||||||
const Minimap({
|
const Minimap({
|
||||||
super.key,
|
super.key,
|
||||||
required this.viewStateNotifier,
|
required this.viewStateNotifier,
|
||||||
|
@ -32,40 +31,40 @@ class Minimap extends StatelessWidget {
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final transformation = snapshot.data;
|
final transformation = snapshot.data;
|
||||||
return CustomPaint(
|
return CustomPaint(
|
||||||
painter: MinimapPainter(
|
painter: _MinimapPainter(
|
||||||
viewportSize: viewportSize,
|
viewportSize: viewportSize,
|
||||||
contentSize: contentSize,
|
contentSize: contentSize,
|
||||||
viewCenterOffset: viewState.position,
|
viewCenterOffset: viewState.position,
|
||||||
viewScale: viewState.scale!,
|
viewScale: viewState.scale!,
|
||||||
transformation: transformation,
|
transformation: transformation,
|
||||||
minimapBorderColor: Colors.white30,
|
minimapBorderColor: ViewerTopOverlay.componentBorderColor,
|
||||||
),
|
),
|
||||||
size: minimapSize,
|
size: const Size.square(ViewerTopOverlay.componentDimension),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
});
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MinimapPainter extends CustomPainter {
|
class _MinimapPainter extends CustomPainter {
|
||||||
final Size contentSize, viewportSize;
|
final Size contentSize, viewportSize;
|
||||||
final Offset viewCenterOffset;
|
final Offset viewCenterOffset;
|
||||||
final double viewScale;
|
final double viewScale;
|
||||||
final Transformation? transformation;
|
final Transformation? transformation;
|
||||||
final Color minimapBorderColor, viewportBorderColor;
|
final Color minimapBorderColor;
|
||||||
|
|
||||||
late final Paint fill, minimapStroke, viewportStroke;
|
late final Paint fill, minimapStroke, viewportStroke;
|
||||||
|
|
||||||
MinimapPainter({
|
_MinimapPainter({
|
||||||
required this.viewportSize,
|
required this.viewportSize,
|
||||||
required this.contentSize,
|
required this.contentSize,
|
||||||
required this.viewCenterOffset,
|
required this.viewCenterOffset,
|
||||||
required this.viewScale,
|
required this.viewScale,
|
||||||
this.transformation,
|
this.transformation,
|
||||||
this.minimapBorderColor = Colors.white,
|
this.minimapBorderColor = Colors.white,
|
||||||
this.viewportBorderColor = Colors.white,
|
|
||||||
}) {
|
}) {
|
||||||
fill = Paint()
|
fill = Paint()
|
||||||
..style = PaintingStyle.fill
|
..style = PaintingStyle.fill
|
||||||
|
@ -75,7 +74,7 @@ class MinimapPainter extends CustomPainter {
|
||||||
..color = minimapBorderColor;
|
..color = minimapBorderColor;
|
||||||
viewportStroke = Paint()
|
viewportStroke = Paint()
|
||||||
..style = PaintingStyle.stroke
|
..style = PaintingStyle.stroke
|
||||||
..color = viewportBorderColor;
|
..color = Colors.white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:aves/model/multipage.dart';
|
import 'package:aves/model/multipage.dart';
|
||||||
import 'package:aves/widgets/common/thumbnail/scroller.dart';
|
import 'package:aves/widgets/common/thumbnail/scroller.dart';
|
||||||
import 'package:aves/widgets/viewer/multipage/controller.dart';
|
import 'package:aves/widgets/viewer/multipage/controller.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/conductor.dart';
|
import 'package:aves/widgets/viewer/view/conductor.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@ import 'package:aves/theme/themes.dart';
|
||||||
import 'package:aves/widgets/common/fx/blurred.dart';
|
import 'package:aves/widgets/common/fx/blurred.dart';
|
||||||
import 'package:aves/widgets/viewer/multipage/conductor.dart';
|
import 'package:aves/widgets/viewer/multipage/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/details/details.dart';
|
import 'package:aves/widgets/viewer/overlay/details/details.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/histogram.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/minimap.dart';
|
import 'package:aves/widgets/viewer/overlay/minimap.dart';
|
||||||
import 'package:aves/widgets/viewer/page_entry_builder.dart';
|
import 'package:aves/widgets/viewer/page_entry_builder.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/conductor.dart';
|
import 'package:aves/widgets/viewer/view/conductor.dart';
|
||||||
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -21,6 +23,9 @@ class ViewerTopOverlay extends StatelessWidget {
|
||||||
final Size availableSize;
|
final Size availableSize;
|
||||||
final EdgeInsets? viewInsets, viewPadding;
|
final EdgeInsets? viewInsets, viewPadding;
|
||||||
|
|
||||||
|
static const Color componentBorderColor = Colors.white30;
|
||||||
|
static const double componentDimension = 96;
|
||||||
|
|
||||||
const ViewerTopOverlay({
|
const ViewerTopOverlay({
|
||||||
super.key,
|
super.key,
|
||||||
required this.entries,
|
required this.entries,
|
||||||
|
@ -45,7 +50,7 @@ class ViewerTopOverlay extends StatelessWidget {
|
||||||
final showInfo = settings.showOverlayInfo;
|
final showInfo = settings.showOverlayInfo;
|
||||||
|
|
||||||
final viewStateConductor = context.read<ViewStateConductor>();
|
final viewStateConductor = context.read<ViewStateConductor>();
|
||||||
final viewStateNotifier = viewStateConductor.getOrCreateController(pageEntry);
|
final viewStateNotifier = viewStateConductor.getOrCreateController(pageEntry).viewStateNotifier;
|
||||||
|
|
||||||
final blurred = settings.enableBlurEffect;
|
final blurred = settings.enableBlurEffect;
|
||||||
final viewInsetsPadding = (viewInsets ?? EdgeInsets.zero) + (viewPadding ?? EdgeInsets.zero);
|
final viewInsetsPadding = (viewInsets ?? EdgeInsets.zero) + (viewPadding ?? EdgeInsets.zero);
|
||||||
|
@ -79,6 +84,9 @@ class ViewerTopOverlay extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
if (settings.showOverlayMinimap)
|
if (settings.showOverlayMinimap)
|
||||||
SafeArea(
|
SafeArea(
|
||||||
top: !showInfo,
|
top: !showInfo,
|
||||||
|
@ -95,7 +103,39 @@ class ViewerTopOverlay extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
const Spacer(),
|
||||||
|
if (settings.overlayHistogramStyle != OverlayHistogramStyle.none)
|
||||||
|
SafeArea(
|
||||||
|
top: !showInfo,
|
||||||
|
minimum: EdgeInsets.only(
|
||||||
|
left: viewInsetsPadding.left,
|
||||||
|
right: viewInsetsPadding.right,
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: scale,
|
||||||
|
child: Selector<ViewStateConductor, ValueNotifier<ImageProvider?>>(
|
||||||
|
selector: (context, vsc) => vsc.getOrCreateController(pageEntry!).fullImageNotifier,
|
||||||
|
builder: (context, fullImageNotifier, child) {
|
||||||
|
return ValueListenableBuilder<ImageProvider?>(
|
||||||
|
valueListenable: fullImageNotifier,
|
||||||
|
builder: (context, fullImage, child) {
|
||||||
|
if (fullImage == null || pageEntry == null) return const SizedBox();
|
||||||
|
return ImageHistogram(
|
||||||
|
entry: pageEntry,
|
||||||
|
image: fullImage,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,7 +13,7 @@ import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
||||||
import 'package:aves/widgets/dialogs/wallpaper_settings_dialog.dart';
|
import 'package:aves/widgets/dialogs/wallpaper_settings_dialog.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/viewer_buttons.dart';
|
import 'package:aves/widgets/viewer/overlay/viewer_buttons.dart';
|
||||||
import 'package:aves/widgets/viewer/video/conductor.dart';
|
import 'package:aves/widgets/viewer/video/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/conductor.dart';
|
import 'package:aves/widgets/viewer/view/conductor.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
@ -94,7 +94,7 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect? _getVisibleRegion(BuildContext context) {
|
Rect? _getVisibleRegion(BuildContext context) {
|
||||||
final viewState = context.read<ViewStateConductor>().getOrCreateController(entry).value;
|
final viewState = context.read<ViewStateConductor>().getOrCreateController(entry).viewState;
|
||||||
final viewportSize = viewState.viewportSize;
|
final viewportSize = viewState.viewportSize;
|
||||||
final contentSize = viewState.contentSize;
|
final contentSize = viewState.contentSize;
|
||||||
final scale = viewState.scale;
|
final scale = viewState.scale;
|
||||||
|
@ -107,7 +107,7 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List?> _getBytes(BuildContext context, Rect displayRegion) async {
|
Future<Uint8List?> _getBytes(BuildContext context, Rect displayRegion) async {
|
||||||
final viewState = context.read<ViewStateConductor>().getOrCreateController(entry).value;
|
final viewState = context.read<ViewStateConductor>().getOrCreateController(entry).viewState;
|
||||||
final scale = viewState.scale;
|
final scale = viewState.scale;
|
||||||
|
|
||||||
final displaySize = entry.displaySize;
|
final displaySize = entry.displaySize;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/widgets/viewer/multipage/conductor.dart';
|
import 'package:aves/widgets/viewer/multipage/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/video/conductor.dart';
|
import 'package:aves/widgets/viewer/video/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/conductor.dart';
|
import 'package:aves/widgets/viewer/view/conductor.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
65
lib/widgets/viewer/view/conductor.dart
Normal file
65
lib/widgets/viewer/view/conductor.dart
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import 'package:aves/model/entry/entry.dart';
|
||||||
|
import 'package:aves/model/view_state.dart';
|
||||||
|
import 'package:aves/widgets/viewer/view/controller.dart';
|
||||||
|
import 'package:aves_magnifier/aves_magnifier.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
|
class ViewStateConductor {
|
||||||
|
final List<ViewStateController> _controllers = [];
|
||||||
|
Size _viewportSize = Size.zero;
|
||||||
|
|
||||||
|
static const maxControllerCount = 3;
|
||||||
|
|
||||||
|
Future<void> dispose() async {
|
||||||
|
_controllers.forEach((v) => v.dispose());
|
||||||
|
_controllers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
set viewportSize(Size size) => _viewportSize = size;
|
||||||
|
|
||||||
|
ViewStateController getOrCreateController(AvesEntry entry) {
|
||||||
|
var controller = getController(entry);
|
||||||
|
if (controller != null) {
|
||||||
|
_controllers.remove(controller);
|
||||||
|
} else {
|
||||||
|
// try to initialize the view state to match magnifier initial state
|
||||||
|
const initialScale = ScaleLevel(ref: ScaleReference.contained);
|
||||||
|
final initialValue = ViewState(
|
||||||
|
position: Offset.zero,
|
||||||
|
scale: ScaleBoundaries(
|
||||||
|
allowOriginalScaleBeyondRange: true,
|
||||||
|
minScale: initialScale,
|
||||||
|
maxScale: initialScale,
|
||||||
|
initialScale: initialScale,
|
||||||
|
viewportSize: _viewportSize,
|
||||||
|
contentSize: entry.displaySize,
|
||||||
|
).initialScale,
|
||||||
|
viewportSize: _viewportSize,
|
||||||
|
contentSize: entry.displaySize,
|
||||||
|
);
|
||||||
|
controller = ViewStateController(
|
||||||
|
entry: entry,
|
||||||
|
viewStateNotifier: ValueNotifier<ViewState>(initialValue),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_controllers.insert(0, controller);
|
||||||
|
while (_controllers.length > maxControllerCount) {
|
||||||
|
_controllers.removeLast().dispose();
|
||||||
|
}
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewStateController? getController(AvesEntry entry) {
|
||||||
|
return _controllers.firstWhereOrNull((c) => c.entry.uri == entry.uri && c.entry.pageId == entry.pageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(AvesEntry entry) {
|
||||||
|
final uris = <AvesEntry>{
|
||||||
|
entry,
|
||||||
|
...?entry.burstEntries,
|
||||||
|
}.map((v) => v.uri).toSet();
|
||||||
|
_controllers.removeWhere((v) => uris.contains(v.entry.uri));
|
||||||
|
}
|
||||||
|
}
|
21
lib/widgets/viewer/view/controller.dart
Normal file
21
lib/widgets/viewer/view/controller.dart
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import 'package:aves/model/entry/entry.dart';
|
||||||
|
import 'package:aves/model/view_state.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/painting.dart';
|
||||||
|
|
||||||
|
class ViewStateController {
|
||||||
|
final AvesEntry entry;
|
||||||
|
final ValueNotifier<ViewState> viewStateNotifier;
|
||||||
|
final ValueNotifier<ImageProvider?> fullImageNotifier = ValueNotifier(null);
|
||||||
|
|
||||||
|
ViewState get viewState => viewStateNotifier.value;
|
||||||
|
|
||||||
|
ViewStateController({
|
||||||
|
required this.entry,
|
||||||
|
required this.viewStateNotifier,
|
||||||
|
});
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
viewStateNotifier.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,60 +0,0 @@
|
||||||
import 'package:aves/model/entry/entry.dart';
|
|
||||||
import 'package:aves/model/view_state.dart';
|
|
||||||
import 'package:aves_magnifier/aves_magnifier.dart';
|
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/rendering.dart';
|
|
||||||
import 'package:tuple/tuple.dart';
|
|
||||||
|
|
||||||
class ViewStateConductor {
|
|
||||||
final List<Tuple2<String, ValueNotifier<ViewState>>> _controllers = [];
|
|
||||||
Size _viewportSize = Size.zero;
|
|
||||||
|
|
||||||
static const maxControllerCount = 3;
|
|
||||||
|
|
||||||
Future<void> dispose() async {
|
|
||||||
_controllers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
set viewportSize(Size size) => _viewportSize = size;
|
|
||||||
|
|
||||||
ValueNotifier<ViewState> getOrCreateController(AvesEntry entry) {
|
|
||||||
var controller = _controllers.firstOrNull;
|
|
||||||
if (controller == null || controller.item1 != entry.uri) {
|
|
||||||
controller = _controllers.firstWhereOrNull((kv) => kv.item1 == entry.uri);
|
|
||||||
if (controller != null) {
|
|
||||||
_controllers.remove(controller);
|
|
||||||
} else {
|
|
||||||
// try to initialize the view state to match magnifier initial state
|
|
||||||
const initialScale = ScaleLevel(ref: ScaleReference.contained);
|
|
||||||
final initialValue = ViewState(
|
|
||||||
position: Offset.zero,
|
|
||||||
scale: ScaleBoundaries(
|
|
||||||
allowOriginalScaleBeyondRange: true,
|
|
||||||
minScale: initialScale,
|
|
||||||
maxScale: initialScale,
|
|
||||||
initialScale: initialScale,
|
|
||||||
viewportSize: _viewportSize,
|
|
||||||
contentSize: entry.displaySize,
|
|
||||||
).initialScale,
|
|
||||||
viewportSize: _viewportSize,
|
|
||||||
contentSize: entry.displaySize,
|
|
||||||
);
|
|
||||||
controller = Tuple2(entry.uri, ValueNotifier<ViewState>(initialValue));
|
|
||||||
}
|
|
||||||
_controllers.insert(0, controller);
|
|
||||||
while (_controllers.length > maxControllerCount) {
|
|
||||||
_controllers.removeLast().item2.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return controller.item2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(AvesEntry entry) {
|
|
||||||
final uris = <AvesEntry>{
|
|
||||||
entry,
|
|
||||||
...?entry.burstEntries,
|
|
||||||
}.map((v) => v.uri).toSet();
|
|
||||||
_controllers.removeWhere((kv) => uris.contains(kv.item1));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,7 +15,7 @@ import 'package:aves/widgets/viewer/controls/controller.dart';
|
||||||
import 'package:aves/widgets/viewer/controls/notifications.dart';
|
import 'package:aves/widgets/viewer/controls/notifications.dart';
|
||||||
import 'package:aves/widgets/viewer/hero.dart';
|
import 'package:aves/widgets/viewer/hero.dart';
|
||||||
import 'package:aves/widgets/viewer/video/conductor.dart';
|
import 'package:aves/widgets/viewer/video/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/conductor.dart';
|
import 'package:aves/widgets/viewer/view/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/error.dart';
|
import 'package:aves/widgets/viewer/visual/error.dart';
|
||||||
import 'package:aves/widgets/viewer/visual/raster.dart';
|
import 'package:aves/widgets/viewer/visual/raster.dart';
|
||||||
import 'package:aves/model/view_state.dart';
|
import 'package:aves/model/view_state.dart';
|
||||||
|
@ -90,7 +90,7 @@ class _EntryPageViewState extends State<EntryPageView> with SingleTickerProvider
|
||||||
|
|
||||||
void _registerWidget(EntryPageView widget) {
|
void _registerWidget(EntryPageView widget) {
|
||||||
final entry = widget.pageEntry;
|
final entry = widget.pageEntry;
|
||||||
_viewStateNotifier = context.read<ViewStateConductor>().getOrCreateController(entry);
|
_viewStateNotifier = context.read<ViewStateConductor>().getOrCreateController(entry).viewStateNotifier;
|
||||||
_magnifierController = AvesMagnifierController();
|
_magnifierController = AvesMagnifierController();
|
||||||
_subscriptions.add(_magnifierController.stateStream.listen(_onViewStateChanged));
|
_subscriptions.add(_magnifierController.stateStream.listen(_onViewStateChanged));
|
||||||
_subscriptions.add(_magnifierController.scaleBoundariesStream.listen(_onViewScaleBoundariesChanged));
|
_subscriptions.add(_magnifierController.scaleBoundariesStream.listen(_onViewScaleBoundariesChanged));
|
||||||
|
|
|
@ -6,9 +6,10 @@ import 'package:aves/model/entry/extensions/images.dart';
|
||||||
import 'package:aves/model/entry/extensions/props.dart';
|
import 'package:aves/model/entry/extensions/props.dart';
|
||||||
import 'package:aves/model/settings/enums/entry_background.dart';
|
import 'package:aves/model/settings/enums/entry_background.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/widgets/common/fx/checkered_decoration.dart';
|
|
||||||
import 'package:aves/widgets/viewer/visual/entry_page_view.dart';
|
|
||||||
import 'package:aves/model/view_state.dart';
|
import 'package:aves/model/view_state.dart';
|
||||||
|
import 'package:aves/widgets/common/fx/checkered_decoration.dart';
|
||||||
|
import 'package:aves/widgets/viewer/controls/notifications.dart';
|
||||||
|
import 'package:aves/widgets/viewer/visual/entry_page_view.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -105,6 +106,7 @@ class _RasterImageViewState extends State<RasterImageView> {
|
||||||
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
|
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
|
||||||
_unregisterFullImage();
|
_unregisterFullImage();
|
||||||
_fullImageLoaded.value = true;
|
_fullImageLoaded.value = true;
|
||||||
|
FullImageLoadedNotification(entry, fullImageProvider).dispatch(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -20,6 +20,8 @@ enum KeepScreenOn { never, videoPlayback, viewerOnly, always }
|
||||||
|
|
||||||
enum MaxBrightness { never, viewerOnly, always }
|
enum MaxBrightness { never, viewerOnly, always }
|
||||||
|
|
||||||
|
enum OverlayHistogramStyle { none, rgb, luminance }
|
||||||
|
|
||||||
enum SlideshowVideoPlayback { skip, playMuted, playWithSound }
|
enum SlideshowVideoPlayback { skip, playMuted, playWithSound }
|
||||||
|
|
||||||
enum SubtitlePosition { top, bottom }
|
enum SubtitlePosition { top, bottom }
|
||||||
|
|
|
@ -87,6 +87,7 @@ class SettingKeys {
|
||||||
static const viewerQuickActionsKey = 'viewer_quick_actions';
|
static const viewerQuickActionsKey = 'viewer_quick_actions';
|
||||||
static const showOverlayOnOpeningKey = 'show_overlay_on_opening';
|
static const showOverlayOnOpeningKey = 'show_overlay_on_opening';
|
||||||
static const showOverlayMinimapKey = 'show_overlay_minimap';
|
static const showOverlayMinimapKey = 'show_overlay_minimap';
|
||||||
|
static const overlayHistogramStyleKey = 'show_overlay_histogram';
|
||||||
static const showOverlayInfoKey = 'show_overlay_info';
|
static const showOverlayInfoKey = 'show_overlay_info';
|
||||||
static const showOverlayDescriptionKey = 'show_overlay_description';
|
static const showOverlayDescriptionKey = 'show_overlay_description';
|
||||||
static const showOverlayRatingTagsKey = 'show_overlay_rating_tags';
|
static const showOverlayRatingTagsKey = 'show_overlay_rating_tags';
|
||||||
|
|
|
@ -98,10 +98,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
|
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.1.0"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -13,6 +13,7 @@ class MpvVideoController extends AvesVideoController {
|
||||||
late Player _instance;
|
late Player _instance;
|
||||||
late VideoController _controller;
|
late VideoController _controller;
|
||||||
late VideoStatus _status;
|
late VideoStatus _status;
|
||||||
|
bool _firstFrameRendered = false;
|
||||||
final List<StreamSubscription> _subscriptions = [];
|
final List<StreamSubscription> _subscriptions = [];
|
||||||
final StreamController<VideoStatus> _statusStreamController = StreamController.broadcast();
|
final StreamController<VideoStatus> _statusStreamController = StreamController.broadcast();
|
||||||
final StreamController<String?> _timedTextStreamController = StreamController.broadcast();
|
final StreamController<String?> _timedTextStreamController = StreamController.broadcast();
|
||||||
|
@ -113,12 +114,17 @@ class MpvVideoController extends AvesVideoController {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initController() {
|
void _initController() {
|
||||||
|
_firstFrameRendered = false;
|
||||||
_controller = VideoController(
|
_controller = VideoController(
|
||||||
_instance,
|
_instance,
|
||||||
configuration: VideoControllerConfiguration(
|
configuration: VideoControllerConfiguration(
|
||||||
enableHardwareAcceleration: settings.enableVideoHardwareAcceleration,
|
enableHardwareAcceleration: settings.enableVideoHardwareAcceleration,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
_controller.waitUntilFirstFrameRendered.then((v) {
|
||||||
|
_firstFrameRendered = true;
|
||||||
|
_statusStreamController.add(_status);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -171,7 +177,7 @@ class MpvVideoController extends AvesVideoController {
|
||||||
case VideoStatus.paused:
|
case VideoStatus.paused:
|
||||||
case VideoStatus.playing:
|
case VideoStatus.playing:
|
||||||
case VideoStatus.completed:
|
case VideoStatus.completed:
|
||||||
return true;
|
return _firstFrameRendered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,10 +98,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
|
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.1.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -172,34 +172,34 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: media_kit
|
name: media_kit
|
||||||
sha256: "272a9f1dd77ed57b48707fdb0ec0e4a048ef958feccc0d0dd751135fe924b63a"
|
sha256: f19151ff1a1724ed8675f066b40e74af6d155fc859cb74487daeae2cbeff53e0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.3+1"
|
||||||
media_kit_libs_android_video:
|
media_kit_libs_android_video:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: media_kit_libs_android_video
|
name: media_kit_libs_android_video
|
||||||
sha256: ddb0d26ecba72bf7117e37e29b6a50f4ba198bbccb4e47246cae1812087dc721
|
sha256: "0a533497d0a982c7146af7dbe226856ef13b05f6d87a6405b1d09d8b40aa2685"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.1"
|
||||||
media_kit_native_event_loop:
|
media_kit_native_event_loop:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: media_kit_native_event_loop
|
name: media_kit_native_event_loop
|
||||||
sha256: "5351f0c28124b5358756515d8619abad182cdefe967468d7fb5b274737cc2f59"
|
sha256: e37ce6fb5fa71b8cf513c6a6cd591367743a342a385e7da621a047dd8ef6f4a4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.7"
|
||||||
media_kit_video:
|
media_kit_video:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: media_kit_video
|
name: media_kit_video
|
||||||
sha256: "3ac0403d67710dfb2bf6aabfa6caff1b163e70fb7e1a88423bc1be569b4df6b3"
|
sha256: e286992beee857fee78ce79ed21fd38addb5af0469e10a322d82cf074beb6214
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.3"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -16,9 +16,9 @@ dependencies:
|
||||||
path: ../aves_utils
|
path: ../aves_utils
|
||||||
collection:
|
collection:
|
||||||
media_kit:
|
media_kit:
|
||||||
media_kit_video:
|
|
||||||
media_kit_native_event_loop:
|
|
||||||
media_kit_libs_android_video:
|
media_kit_libs_android_video:
|
||||||
|
media_kit_native_event_loop:
|
||||||
|
media_kit_video:
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
|
|
32
pubspec.lock
32
pubspec.lock
|
@ -347,10 +347,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
|
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.1.0"
|
||||||
ffmpeg_kit_flutter:
|
ffmpeg_kit_flutter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -516,10 +516,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_markdown
|
name: flutter_markdown
|
||||||
sha256: "4b1bfbb802d76320a1a46d9ce984106135093efd9d969765d07c2125af107bdf"
|
sha256: "2b206d397dd7836ea60035b2d43825c8a303a76a5098e66f42d55a753e18d431"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.17"
|
version: "0.6.17+1"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -835,34 +835,34 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: media_kit
|
name: media_kit
|
||||||
sha256: "272a9f1dd77ed57b48707fdb0ec0e4a048ef958feccc0d0dd751135fe924b63a"
|
sha256: f19151ff1a1724ed8675f066b40e74af6d155fc859cb74487daeae2cbeff53e0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.3+1"
|
||||||
media_kit_libs_android_video:
|
media_kit_libs_android_video:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: media_kit_libs_android_video
|
name: media_kit_libs_android_video
|
||||||
sha256: ddb0d26ecba72bf7117e37e29b6a50f4ba198bbccb4e47246cae1812087dc721
|
sha256: "0a533497d0a982c7146af7dbe226856ef13b05f6d87a6405b1d09d8b40aa2685"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.1"
|
||||||
media_kit_native_event_loop:
|
media_kit_native_event_loop:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: media_kit_native_event_loop
|
name: media_kit_native_event_loop
|
||||||
sha256: "5351f0c28124b5358756515d8619abad182cdefe967468d7fb5b274737cc2f59"
|
sha256: e37ce6fb5fa71b8cf513c6a6cd591367743a342a385e7da621a047dd8ef6f4a4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.7"
|
||||||
media_kit_video:
|
media_kit_video:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: media_kit_video
|
name: media_kit_video
|
||||||
sha256: "3ac0403d67710dfb2bf6aabfa6caff1b163e70fb7e1a88423bc1be569b4df6b3"
|
sha256: e286992beee857fee78ce79ed21fd38addb5af0469e10a322d82cf074beb6214
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.3"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1531,10 +1531,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_android
|
name: url_launcher_android
|
||||||
sha256: "78cb6dea3e93148615109e58e42c35d1ffbf5ef66c44add673d0ab75f12ff3af"
|
sha256: "3dd2388cc0c42912eee04434531a26a82512b9cb1827e0214430c9bcbddfe025"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.37"
|
version: "6.0.38"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1691,10 +1691,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff
|
sha256: f0c26453a2d47aa4c2570c6a033246a3fc62da2fe23c7ffdd0a7495086dc0247
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.2"
|
||||||
xml:
|
xml:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -142,6 +142,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -487,6 +490,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -640,6 +644,9 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"be": [
|
"be": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"viewerTransitionSlide",
|
"viewerTransitionSlide",
|
||||||
"viewerTransitionFade",
|
"viewerTransitionFade",
|
||||||
"viewerTransitionZoomIn",
|
"viewerTransitionZoomIn",
|
||||||
|
@ -920,6 +927,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -1127,6 +1135,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -1473,6 +1484,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -1638,14 +1650,46 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"cs": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
|
"de": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
"el": [
|
"el": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"aboutDataUsageSectionTitle",
|
"aboutDataUsageSectionTitle",
|
||||||
"aboutDataUsageData",
|
"aboutDataUsageData",
|
||||||
"aboutDataUsageCache",
|
"aboutDataUsageCache",
|
||||||
"aboutDataUsageDatabase",
|
"aboutDataUsageDatabase",
|
||||||
"aboutDataUsageMisc",
|
"aboutDataUsageMisc",
|
||||||
"aboutDataUsageInternal",
|
"aboutDataUsageInternal",
|
||||||
"aboutDataUsageExternal"
|
"aboutDataUsageExternal",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
|
"es": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
|
"eu": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
|
@ -1700,6 +1744,9 @@
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
"vaultLockTypePin",
|
"vaultLockTypePin",
|
||||||
"vaultLockTypePassword",
|
"vaultLockTypePassword",
|
||||||
|
@ -1996,6 +2043,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -2159,6 +2207,13 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
"gl": [
|
"gl": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"saveCopyButtonLabel",
|
"saveCopyButtonLabel",
|
||||||
|
@ -2200,6 +2255,9 @@
|
||||||
"lengthUnitPercent",
|
"lengthUnitPercent",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -2537,6 +2595,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -2863,6 +2922,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -3209,6 +3271,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -3515,6 +3578,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -3861,6 +3927,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -4026,6 +4093,27 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"hu": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
|
"id": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
|
"it": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"saveCopyButtonLabel",
|
"saveCopyButtonLabel",
|
||||||
|
@ -4046,6 +4134,9 @@
|
||||||
"albumTierVaults",
|
"albumTierVaults",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"videoResumptionModeNever",
|
"videoResumptionModeNever",
|
||||||
"videoResumptionModeAlways",
|
"videoResumptionModeAlways",
|
||||||
|
@ -4068,6 +4159,7 @@
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsCollectionBurstPatternsTile",
|
"settingsCollectionBurstPatternsTile",
|
||||||
"settingsCollectionBurstPatternsNone",
|
"settingsCollectionBurstPatternsNone",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsVideoPlaybackTile",
|
"settingsVideoPlaybackTile",
|
||||||
"settingsVideoPlaybackPageTitle",
|
"settingsVideoPlaybackPageTitle",
|
||||||
|
@ -4218,6 +4310,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -4564,6 +4659,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -4729,6 +4825,13 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ko": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
"lt": [
|
"lt": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"saveCopyButtonLabel",
|
"saveCopyButtonLabel",
|
||||||
|
@ -4754,6 +4857,9 @@
|
||||||
"lengthUnitPercent",
|
"lengthUnitPercent",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
"vaultLockTypePin",
|
"vaultLockTypePin",
|
||||||
"vaultLockTypePassword",
|
"vaultLockTypePassword",
|
||||||
|
@ -4796,6 +4902,7 @@
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsCollectionBurstPatternsTile",
|
"settingsCollectionBurstPatternsTile",
|
||||||
"settingsCollectionBurstPatternsNone",
|
"settingsCollectionBurstPatternsNone",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsVideoPlaybackTile",
|
"settingsVideoPlaybackTile",
|
||||||
"settingsVideoPlaybackPageTitle",
|
"settingsVideoPlaybackPageTitle",
|
||||||
|
@ -4977,6 +5084,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -5323,6 +5433,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -5608,6 +5719,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -5954,6 +6068,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -6133,6 +6248,9 @@
|
||||||
"cropAspectRatioSquare",
|
"cropAspectRatioSquare",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
"settingsVideoEnablePip",
|
"settingsVideoEnablePip",
|
||||||
"videoResumptionModeNever",
|
"videoResumptionModeNever",
|
||||||
|
@ -6154,6 +6272,7 @@
|
||||||
"settingsAskEverytime",
|
"settingsAskEverytime",
|
||||||
"settingsCollectionBurstPatternsTile",
|
"settingsCollectionBurstPatternsTile",
|
||||||
"settingsCollectionBurstPatternsNone",
|
"settingsCollectionBurstPatternsNone",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsVideoPlaybackTile",
|
"settingsVideoPlaybackTile",
|
||||||
"settingsVideoPlaybackPageTitle",
|
"settingsVideoPlaybackPageTitle",
|
||||||
"settingsVideoResumptionModeTile",
|
"settingsVideoResumptionModeTile",
|
||||||
|
@ -6184,6 +6303,9 @@
|
||||||
"albumTierVaults",
|
"albumTierVaults",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
|
@ -6225,6 +6347,7 @@
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsCollectionBurstPatternsTile",
|
"settingsCollectionBurstPatternsTile",
|
||||||
"settingsCollectionBurstPatternsNone",
|
"settingsCollectionBurstPatternsNone",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowRatingTags",
|
"settingsViewerShowRatingTags",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsVideoPlaybackTile",
|
"settingsVideoPlaybackTile",
|
||||||
|
@ -6247,6 +6370,9 @@
|
||||||
"nn": [
|
"nn": [
|
||||||
"sourceStateCataloguing",
|
"sourceStateCataloguing",
|
||||||
"accessibilityAnimationsKeep",
|
"accessibilityAnimationsKeep",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"settingsVideoEnablePip",
|
"settingsVideoEnablePip",
|
||||||
"widgetTapUpdateWidget",
|
"widgetTapUpdateWidget",
|
||||||
"authenticateToConfigureVault",
|
"authenticateToConfigureVault",
|
||||||
|
@ -6266,6 +6392,7 @@
|
||||||
"collectionActionShowTitleSearch",
|
"collectionActionShowTitleSearch",
|
||||||
"collectionActionHideTitleSearch",
|
"collectionActionHideTitleSearch",
|
||||||
"drawerCollectionAnimated",
|
"drawerCollectionAnimated",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsSlideshowAnimatedZoomEffect",
|
"settingsSlideshowAnimatedZoomEffect",
|
||||||
"settingsHiddenItemsTabFilters",
|
"settingsHiddenItemsTabFilters",
|
||||||
"settingsHiddenFiltersBanner",
|
"settingsHiddenFiltersBanner",
|
||||||
|
@ -6427,6 +6554,9 @@
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"unitSystemMetric",
|
"unitSystemMetric",
|
||||||
|
@ -6721,6 +6851,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
"settingsViewerShowRatingTags",
|
"settingsViewerShowRatingTags",
|
||||||
|
@ -6883,14 +7014,25 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"pl": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"aboutDataUsageSectionTitle",
|
"aboutDataUsageSectionTitle",
|
||||||
"aboutDataUsageData",
|
"aboutDataUsageData",
|
||||||
"aboutDataUsageCache",
|
"aboutDataUsageCache",
|
||||||
"aboutDataUsageDatabase",
|
"aboutDataUsageDatabase",
|
||||||
"aboutDataUsageMisc",
|
"aboutDataUsageMisc",
|
||||||
"aboutDataUsageInternal",
|
"aboutDataUsageInternal",
|
||||||
"aboutDataUsageExternal"
|
"aboutDataUsageExternal",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ro": [
|
"ro": [
|
||||||
|
@ -6904,6 +7046,9 @@
|
||||||
"cropAspectRatioSquare",
|
"cropAspectRatioSquare",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"videoResumptionModeNever",
|
"videoResumptionModeNever",
|
||||||
"videoResumptionModeAlways",
|
"videoResumptionModeAlways",
|
||||||
"widgetTapUpdateWidget",
|
"widgetTapUpdateWidget",
|
||||||
|
@ -6916,6 +7061,7 @@
|
||||||
"aboutDataUsageInternal",
|
"aboutDataUsageInternal",
|
||||||
"aboutDataUsageExternal",
|
"aboutDataUsageExternal",
|
||||||
"settingsAskEverytime",
|
"settingsAskEverytime",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsVideoPlaybackTile",
|
"settingsVideoPlaybackTile",
|
||||||
"settingsVideoPlaybackPageTitle",
|
"settingsVideoPlaybackPageTitle",
|
||||||
"settingsVideoResumptionModeTile",
|
"settingsVideoResumptionModeTile",
|
||||||
|
@ -6923,6 +7069,13 @@
|
||||||
"tagEditorDiscardDialogMessage"
|
"tagEditorDiscardDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ru": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
"sk": [
|
"sk": [
|
||||||
"itemCount",
|
"itemCount",
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
@ -6950,6 +7103,9 @@
|
||||||
"lengthUnitPercent",
|
"lengthUnitPercent",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
"vaultLockTypePin",
|
"vaultLockTypePin",
|
||||||
"vaultLockTypePassword",
|
"vaultLockTypePassword",
|
||||||
|
@ -7218,6 +7374,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -7544,6 +7701,9 @@
|
||||||
"nameConflictStrategyRename",
|
"nameConflictStrategyRename",
|
||||||
"nameConflictStrategyReplace",
|
"nameConflictStrategyReplace",
|
||||||
"nameConflictStrategySkip",
|
"nameConflictStrategySkip",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"themeBrightnessLight",
|
"themeBrightnessLight",
|
||||||
|
@ -7890,6 +8050,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -8083,6 +8244,9 @@
|
||||||
"lengthUnitPercent",
|
"lengthUnitPercent",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
"vaultLockTypePin",
|
"vaultLockTypePin",
|
||||||
"vaultLockTypePassword",
|
"vaultLockTypePassword",
|
||||||
|
@ -8285,6 +8449,7 @@
|
||||||
"settingsViewerOverlayTile",
|
"settingsViewerOverlayTile",
|
||||||
"settingsViewerOverlayPageTitle",
|
"settingsViewerOverlayPageTitle",
|
||||||
"settingsViewerShowOverlayOnOpening",
|
"settingsViewerShowOverlayOnOpening",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowMinimap",
|
"settingsViewerShowMinimap",
|
||||||
"settingsViewerShowInformation",
|
"settingsViewerShowInformation",
|
||||||
"settingsViewerShowInformationSubtitle",
|
"settingsViewerShowInformationSubtitle",
|
||||||
|
@ -8471,6 +8636,9 @@
|
||||||
"lengthUnitPercent",
|
"lengthUnitPercent",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
"vaultLockTypePin",
|
"vaultLockTypePin",
|
||||||
"vaultLockTypePassword",
|
"vaultLockTypePassword",
|
||||||
|
@ -8511,6 +8679,7 @@
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsCollectionBurstPatternsTile",
|
"settingsCollectionBurstPatternsTile",
|
||||||
"settingsCollectionBurstPatternsNone",
|
"settingsCollectionBurstPatternsNone",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsVideoPlaybackTile",
|
"settingsVideoPlaybackTile",
|
||||||
"settingsVideoPlaybackPageTitle",
|
"settingsVideoPlaybackPageTitle",
|
||||||
"settingsVideoResumptionModeTile",
|
"settingsVideoResumptionModeTile",
|
||||||
|
@ -8523,6 +8692,13 @@
|
||||||
"tagPlaceholderState"
|
"tagPlaceholderState"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"uk": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"saveCopyButtonLabel",
|
"saveCopyButtonLabel",
|
||||||
"chipActionGoToPlacePage",
|
"chipActionGoToPlacePage",
|
||||||
|
@ -8537,6 +8713,9 @@
|
||||||
"lengthUnitPercent",
|
"lengthUnitPercent",
|
||||||
"maxBrightnessNever",
|
"maxBrightnessNever",
|
||||||
"maxBrightnessAlways",
|
"maxBrightnessAlways",
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"vaultLockTypePattern",
|
"vaultLockTypePattern",
|
||||||
"vaultLockTypePin",
|
"vaultLockTypePin",
|
||||||
"settingsVideoEnablePip",
|
"settingsVideoEnablePip",
|
||||||
|
@ -8573,6 +8752,7 @@
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsCollectionBurstPatternsTile",
|
"settingsCollectionBurstPatternsTile",
|
||||||
"settingsCollectionBurstPatternsNone",
|
"settingsCollectionBurstPatternsNone",
|
||||||
|
"settingsViewerShowHistogram",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsVideoPlaybackTile",
|
"settingsVideoPlaybackTile",
|
||||||
"settingsVideoPlaybackPageTitle",
|
"settingsVideoPlaybackPageTitle",
|
||||||
|
@ -8588,12 +8768,16 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh_Hant": [
|
"zh_Hant": [
|
||||||
|
"overlayHistogramNone",
|
||||||
|
"overlayHistogramRGB",
|
||||||
|
"overlayHistogramLuminance",
|
||||||
"aboutDataUsageSectionTitle",
|
"aboutDataUsageSectionTitle",
|
||||||
"aboutDataUsageData",
|
"aboutDataUsageData",
|
||||||
"aboutDataUsageCache",
|
"aboutDataUsageCache",
|
||||||
"aboutDataUsageDatabase",
|
"aboutDataUsageDatabase",
|
||||||
"aboutDataUsageMisc",
|
"aboutDataUsageMisc",
|
||||||
"aboutDataUsageInternal",
|
"aboutDataUsageInternal",
|
||||||
"aboutDataUsageExternal"
|
"aboutDataUsageExternal",
|
||||||
|
"settingsViewerShowHistogram"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue