viewer quick action defaults;
viewer overlay location collapse in landscape; popup menu icon action shape
This commit is contained in:
parent
a074ff5dd6
commit
ad3b241e1d
5 changed files with 137 additions and 87 deletions
|
@ -12,6 +12,8 @@ class OverlayMetadata extends Equatable {
|
||||||
|
|
||||||
bool get isEmpty => aperture == null && exposureTime == null && focalLength == null && iso == null;
|
bool get isEmpty => aperture == null && exposureTime == null && focalLength == null && iso == null;
|
||||||
|
|
||||||
|
bool get isNotEmpty => !isEmpty;
|
||||||
|
|
||||||
const OverlayMetadata({
|
const OverlayMetadata({
|
||||||
this.aperture,
|
this.aperture,
|
||||||
this.exposureTime,
|
this.exposureTime,
|
||||||
|
|
|
@ -60,9 +60,11 @@ class SettingsDefaults {
|
||||||
|
|
||||||
// viewer
|
// viewer
|
||||||
static const viewerQuickActions = [
|
static const viewerQuickActions = [
|
||||||
|
EntryAction.rotateScreen,
|
||||||
EntryAction.toggleFavourite,
|
EntryAction.toggleFavourite,
|
||||||
EntryAction.share,
|
EntryAction.share,
|
||||||
EntryAction.rotateScreen,
|
EntryAction.edit,
|
||||||
|
EntryAction.delete,
|
||||||
];
|
];
|
||||||
static const showOverlayOnOpening = true;
|
static const showOverlayOnOpening = true;
|
||||||
static const showOverlayMinimap = false;
|
static const showOverlayMinimap = false;
|
||||||
|
|
|
@ -361,27 +361,38 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget buildItem(EntrySetAction action) => Expanded(
|
Widget buildItem(EntrySetAction action) => Expanded(
|
||||||
child: PopupMenuItem(
|
child: Material(
|
||||||
value: action,
|
shape: const RoundedRectangleBorder(
|
||||||
enabled: canApply(action),
|
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||||
child: Tooltip(
|
),
|
||||||
message: action.getText(context),
|
clipBehavior: Clip.antiAlias,
|
||||||
child: Center(child: action.getIcon()),
|
child: PopupMenuItem(
|
||||||
|
value: action,
|
||||||
|
enabled: canApply(action),
|
||||||
|
child: Tooltip(
|
||||||
|
message: action.getText(context),
|
||||||
|
child: Center(child: action.getIcon()),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return PopupMenuItem(
|
return PopupMenuItem(
|
||||||
child: Row(
|
child: TooltipTheme(
|
||||||
children: [
|
data: TooltipTheme.of(context).copyWith(
|
||||||
buildDivider(),
|
preferBelow: false,
|
||||||
buildItem(EntrySetAction.rotateCCW),
|
),
|
||||||
buildDivider(),
|
child: Row(
|
||||||
buildItem(EntrySetAction.rotateCW),
|
children: [
|
||||||
buildDivider(),
|
buildDivider(),
|
||||||
buildItem(EntrySetAction.flip),
|
buildItem(EntrySetAction.rotateCCW),
|
||||||
buildDivider(),
|
buildDivider(),
|
||||||
],
|
buildItem(EntrySetAction.rotateCW),
|
||||||
|
buildDivider(),
|
||||||
|
buildItem(EntrySetAction.flip),
|
||||||
|
buildDivider(),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,8 +139,7 @@ class ViewerDetailOverlayContent extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final infoMaxWidth = availableWidth - padding.horizontal;
|
final infoMaxWidth = availableWidth - padding.horizontal;
|
||||||
final positionTitle = _PositionTitleRow(entry: pageEntry, collectionPosition: position, multiPageController: multiPageController);
|
final positionTitle = _PositionTitleRow(entry: pageEntry, collectionPosition: position, multiPageController: multiPageController);
|
||||||
final hasShootingDetails = details != null && !details!.isEmpty && settings.showOverlayShootingDetails;
|
final showShooting = settings.showOverlayShootingDetails;
|
||||||
final animationDuration = context.select<DurationsData, Duration>((v) => v.viewerOverlayChangeAnimation);
|
|
||||||
|
|
||||||
return DefaultTextStyle(
|
return DefaultTextStyle(
|
||||||
style: Theme.of(context).textTheme.bodyText2!.copyWith(
|
style: Theme.of(context).textTheme.bodyText2!.copyWith(
|
||||||
|
@ -156,40 +155,38 @@ class ViewerDetailOverlayContent extends StatelessWidget {
|
||||||
builder: (context, orientation, child) {
|
builder: (context, orientation, child) {
|
||||||
final twoColumns = orientation == Orientation.landscape && infoMaxWidth / 2 > _subRowMinWidth;
|
final twoColumns = orientation == Orientation.landscape && infoMaxWidth / 2 > _subRowMinWidth;
|
||||||
final subRowWidth = twoColumns ? min(_subRowMinWidth, infoMaxWidth / 2) : infoMaxWidth;
|
final subRowWidth = twoColumns ? min(_subRowMinWidth, infoMaxWidth / 2) : infoMaxWidth;
|
||||||
|
final collapsedShooting = twoColumns && showShooting;
|
||||||
|
final collapsedLocation = twoColumns && !showShooting;
|
||||||
|
|
||||||
|
final rows = <Widget>[];
|
||||||
|
if (positionTitle.isNotEmpty) {
|
||||||
|
rows.add(positionTitle);
|
||||||
|
rows.add(const SizedBox(height: _interRowPadding));
|
||||||
|
}
|
||||||
|
if (twoColumns) {
|
||||||
|
rows.add(
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
_buildDateSubRow(subRowWidth),
|
||||||
|
if (collapsedShooting) _buildShootingSubRow(context, subRowWidth),
|
||||||
|
if (collapsedLocation) _buildLocationSubRow(context, subRowWidth),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
rows.add(_buildDateSubRow(subRowWidth));
|
||||||
|
if (showShooting) {
|
||||||
|
rows.add(_buildShootingFullRow(context, subRowWidth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!collapsedLocation) {
|
||||||
|
rows.add(_buildLocationFullRow(context));
|
||||||
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: rows,
|
||||||
if (positionTitle.isNotEmpty) positionTitle,
|
|
||||||
if (twoColumns)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: _interRowPadding),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: subRowWidth,
|
|
||||||
child: _DateRow(
|
|
||||||
entry: pageEntry,
|
|
||||||
multiPageController: multiPageController,
|
|
||||||
)),
|
|
||||||
_buildDuoShootingRow(subRowWidth, hasShootingDetails, animationDuration),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else ...[
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.only(top: _interRowPadding),
|
|
||||||
width: subRowWidth,
|
|
||||||
child: _DateRow(
|
|
||||||
entry: pageEntry,
|
|
||||||
multiPageController: multiPageController,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
_buildSoloShootingRow(subRowWidth, hasShootingDetails, animationDuration),
|
|
||||||
],
|
|
||||||
_buildSoloLocationRow(animationDuration),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -197,56 +194,88 @@ class ViewerDetailOverlayContent extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSoloLocationRow(Duration animationDuration) => AnimatedSwitcher(
|
Widget _buildDateSubRow(double subRowWidth) => SizedBox(
|
||||||
duration: animationDuration,
|
width: subRowWidth,
|
||||||
switchInCurve: Curves.easeInOutCubic,
|
child: _DateRow(
|
||||||
switchOutCurve: Curves.easeInOutCubic,
|
entry: pageEntry,
|
||||||
transitionBuilder: _soloTransition,
|
multiPageController: multiPageController,
|
||||||
child: pageEntry.hasGps
|
),
|
||||||
? Container(
|
|
||||||
padding: const EdgeInsets.only(top: _interRowPadding),
|
|
||||||
child: _LocationRow(entry: pageEntry),
|
|
||||||
)
|
|
||||||
: const SizedBox(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildSoloShootingRow(double subRowWidth, bool hasShootingDetails, Duration animationDuration) => AnimatedSwitcher(
|
Widget _buildShootingFullRow(BuildContext context, double subRowWidth) => _buildFullRowSwitcher(
|
||||||
duration: animationDuration,
|
context: context,
|
||||||
switchInCurve: Curves.easeInOutCubic,
|
visible: details != null && details!.isNotEmpty,
|
||||||
switchOutCurve: Curves.easeInOutCubic,
|
builder: (context) => SizedBox(
|
||||||
transitionBuilder: _soloTransition,
|
width: subRowWidth,
|
||||||
child: hasShootingDetails
|
child: _ShootingRow(details!),
|
||||||
? Container(
|
),
|
||||||
padding: const EdgeInsets.only(top: _interRowPadding),
|
|
||||||
width: subRowWidth,
|
|
||||||
child: _ShootingRow(details!),
|
|
||||||
)
|
|
||||||
: const SizedBox(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildDuoShootingRow(double subRowWidth, bool hasShootingDetails, Duration animationDuration) => AnimatedSwitcher(
|
Widget _buildShootingSubRow(BuildContext context, double subRowWidth) => _buildSubRowSwitcher(
|
||||||
duration: animationDuration,
|
context: context,
|
||||||
|
subRowWidth: subRowWidth,
|
||||||
|
visible: details != null && details!.isNotEmpty,
|
||||||
|
builder: (context) => _ShootingRow(details!),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildLocationFullRow(BuildContext context) => _buildFullRowSwitcher(
|
||||||
|
context: context,
|
||||||
|
visible: pageEntry.hasGps,
|
||||||
|
builder: (context) => _LocationRow(entry: pageEntry),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildLocationSubRow(BuildContext context, double subRowWidth) => _buildSubRowSwitcher(
|
||||||
|
context: context,
|
||||||
|
subRowWidth: subRowWidth,
|
||||||
|
visible: pageEntry.hasGps,
|
||||||
|
builder: (context) => _LocationRow(entry: pageEntry),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildSubRowSwitcher({
|
||||||
|
required BuildContext context,
|
||||||
|
required double subRowWidth,
|
||||||
|
required bool visible,
|
||||||
|
required WidgetBuilder builder,
|
||||||
|
}) =>
|
||||||
|
AnimatedSwitcher(
|
||||||
|
duration: context.select<DurationsData, Duration>((v) => v.viewerOverlayChangeAnimation),
|
||||||
switchInCurve: Curves.easeInOutCubic,
|
switchInCurve: Curves.easeInOutCubic,
|
||||||
switchOutCurve: Curves.easeInOutCubic,
|
switchOutCurve: Curves.easeInOutCubic,
|
||||||
transitionBuilder: (child, animation) => FadeTransition(
|
transitionBuilder: (child, animation) => FadeTransition(
|
||||||
opacity: animation,
|
opacity: animation,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
child: hasShootingDetails
|
child: visible
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
width: subRowWidth,
|
width: subRowWidth,
|
||||||
child: _ShootingRow(details!),
|
child: builder(context),
|
||||||
)
|
)
|
||||||
: const SizedBox(),
|
: const SizedBox(),
|
||||||
);
|
);
|
||||||
|
|
||||||
static Widget _soloTransition(Widget child, Animation<double> animation) => FadeTransition(
|
Widget _buildFullRowSwitcher({
|
||||||
opacity: animation,
|
required BuildContext context,
|
||||||
child: SizeTransition(
|
required bool visible,
|
||||||
axisAlignment: 1,
|
required WidgetBuilder builder,
|
||||||
sizeFactor: animation,
|
}) =>
|
||||||
child: child,
|
AnimatedSwitcher(
|
||||||
|
duration: context.select<DurationsData, Duration>((v) => v.viewerOverlayChangeAnimation),
|
||||||
|
switchInCurve: Curves.easeInOutCubic,
|
||||||
|
switchOutCurve: Curves.easeInOutCubic,
|
||||||
|
transitionBuilder: (child, animation) => FadeTransition(
|
||||||
|
opacity: animation,
|
||||||
|
child: SizeTransition(
|
||||||
|
axisAlignment: 1,
|
||||||
|
sizeFactor: animation,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
child: visible
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.only(top: _interRowPadding),
|
||||||
|
child: builder(context),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,11 +352,17 @@ class ViewerButtonRowContent extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget buildItem(EntryAction action) => Expanded(
|
Widget buildItem(EntryAction action) => Expanded(
|
||||||
child: PopupMenuItem(
|
child: Material(
|
||||||
value: action,
|
shape: const RoundedRectangleBorder(
|
||||||
child: Tooltip(
|
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||||
message: action.getText(context),
|
),
|
||||||
child: Center(child: action.getIcon()),
|
clipBehavior: Clip.antiAlias,
|
||||||
|
child: PopupMenuItem(
|
||||||
|
value: action,
|
||||||
|
child: Tooltip(
|
||||||
|
message: action.getText(context),
|
||||||
|
child: Center(child: action.getIcon()),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue