#181 viewer: fixed "actual size" zoom, allow zooming out small items to actual size, fixed minimap for unsized items
This commit is contained in:
parent
d8210ef075
commit
835a2ed18e
9 changed files with 31 additions and 17 deletions
|
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- optional recycle bin to keep deleted items for 30 days
|
||||||
- Viewer: actions to copy/move to album
|
- Viewer: actions to copy/move to album
|
||||||
- Indonesian translation (thanks MeFinity)
|
- Indonesian translation (thanks MeFinity)
|
||||||
|
|
||||||
|
@ -13,6 +14,8 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
- Viewer: action menu reorganization
|
- Viewer: action menu reorganization
|
||||||
- Viewer: `Export` action renamed to `Convert`
|
- Viewer: `Export` action renamed to `Convert`
|
||||||
|
- Viewer: actual size zoom level respects device pixel ratio
|
||||||
|
- Viewer: allow zooming out small items to actual size
|
||||||
- Collection: improved performance for sort/group by name
|
- Collection: improved performance for sort/group by name
|
||||||
- load previous top items on startup
|
- load previous top items on startup
|
||||||
- upgraded Flutter to stable v2.10.1
|
- upgraded Flutter to stable v2.10.1
|
||||||
|
|
|
@ -378,7 +378,7 @@
|
||||||
"appExportSettings": "Pengaturan",
|
"appExportSettings": "Pengaturan",
|
||||||
|
|
||||||
"settingsSectionNavigation": "Navigasi",
|
"settingsSectionNavigation": "Navigasi",
|
||||||
"settingsHome": "Home",
|
"settingsHome": "Beranda",
|
||||||
"settingsKeepScreenOnTile": "Biarkan layarnya menyala",
|
"settingsKeepScreenOnTile": "Biarkan layarnya menyala",
|
||||||
"settingsKeepScreenOnTitle": "Biarkan Layarnya Menyala",
|
"settingsKeepScreenOnTitle": "Biarkan Layarnya Menyala",
|
||||||
"settingsDoubleBackExit": "Ketuk “kembali” dua kali untuk keluar",
|
"settingsDoubleBackExit": "Ketuk “kembali” dua kali untuk keluar",
|
||||||
|
|
|
@ -71,6 +71,7 @@ class MagnifierController {
|
||||||
position = position ?? this.position;
|
position = position ?? this.position;
|
||||||
scale = scale ?? this.scale;
|
scale = scale ?? this.scale;
|
||||||
if (this.position == position && this.scale == scale) return;
|
if (this.position == position && this.scale == scale) return;
|
||||||
|
assert((scale ?? 0) >= 0);
|
||||||
|
|
||||||
previousState = currentState;
|
previousState = currentState;
|
||||||
_setState(MagnifierState(
|
_setState(MagnifierState(
|
||||||
|
@ -127,7 +128,7 @@ class MagnifierController {
|
||||||
case ScaleState.covering:
|
case ScaleState.covering:
|
||||||
return _clamp(ScaleLevel.scaleForCovering(scaleBoundaries.viewportSize, scaleBoundaries.childSize));
|
return _clamp(ScaleLevel.scaleForCovering(scaleBoundaries.viewportSize, scaleBoundaries.childSize));
|
||||||
case ScaleState.originalSize:
|
case ScaleState.originalSize:
|
||||||
return _clamp(1.0);
|
return _clamp(scaleBoundaries.originalScale);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/widgets/common/magnifier/controller/controller.dart';
|
import 'package:aves/widgets/common/magnifier/controller/controller.dart';
|
||||||
import 'package:aves/widgets/common/magnifier/controller/controller_delegate.dart';
|
import 'package:aves/widgets/common/magnifier/controller/controller_delegate.dart';
|
||||||
import 'package:aves/widgets/common/magnifier/controller/state.dart';
|
import 'package:aves/widgets/common/magnifier/controller/state.dart';
|
||||||
|
@ -132,7 +134,7 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
|
||||||
|
|
||||||
updateScaleStateFromNewScale(newScale, ChangeSource.gesture);
|
updateScaleStateFromNewScale(newScale, ChangeSource.gesture);
|
||||||
updateMultiple(
|
updateMultiple(
|
||||||
scale: newScale,
|
scale: max(0, newScale),
|
||||||
position: newPosition,
|
position: newPosition,
|
||||||
source: ChangeSource.gesture,
|
source: ChangeSource.gesture,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:math';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:aves/widgets/common/magnifier/controller/controller.dart';
|
import 'package:aves/widgets/common/magnifier/controller/controller.dart';
|
||||||
|
@ -41,11 +42,13 @@ class ScaleBoundaries extends Equatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double get minScale => _scaleForLevel(_minScale);
|
double get originalScale => 1.0 / window.devicePixelRatio;
|
||||||
|
|
||||||
double get maxScale => _scaleForLevel(_maxScale).clamp(minScale, double.infinity);
|
double get minScale => {_scaleForLevel(_minScale), originalScale, initialScale}.fold(double.infinity, min);
|
||||||
|
|
||||||
double get initialScale => _scaleForLevel(_initialScale).clamp(minScale, maxScale);
|
double get maxScale => {_scaleForLevel(_maxScale), originalScale, initialScale}.fold(0, max);
|
||||||
|
|
||||||
|
double get initialScale => _scaleForLevel(_initialScale);
|
||||||
|
|
||||||
Offset get _viewportCenter => viewportSize.center(Offset.zero);
|
Offset get _viewportCenter => viewportSize.center(Offset.zero);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class DecoratedThumbnail extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
child = Stack(
|
child = Stack(
|
||||||
alignment: AlignmentDirectional.bottomStart,
|
fit: StackFit.passthrough,
|
||||||
children: [
|
children: [
|
||||||
child,
|
child,
|
||||||
ThumbnailEntryOverlay(entry: entry),
|
ThumbnailEntryOverlay(entry: entry),
|
||||||
|
|
|
@ -38,11 +38,13 @@ class ThumbnailEntryOverlay extends StatelessWidget {
|
||||||
if (entry.trashed && context.select<GridThemeData, bool>((t) => t.showTrash)) TrashIcon(trashDaysLeft: entry.trashDaysLeft),
|
if (entry.trashed && context.select<GridThemeData, bool>((t) => t.showTrash)) TrashIcon(trashDaysLeft: entry.trashDaysLeft),
|
||||||
];
|
];
|
||||||
if (children.isEmpty) return const SizedBox();
|
if (children.isEmpty) return const SizedBox();
|
||||||
if (children.length == 1) return children.first;
|
return Align(
|
||||||
return Column(
|
alignment: AlignmentDirectional.bottomStart,
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: children,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,8 @@ class MinimapPainter extends CustomPainter {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
|
if (entrySize.width <= 0 || entrySize.height <= 0) return;
|
||||||
|
|
||||||
final viewSize = entrySize * viewScale;
|
final viewSize = entrySize * viewScale;
|
||||||
if (viewSize.isEmpty) return;
|
if (viewSize.isEmpty) return;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
class ViewState {
|
@immutable
|
||||||
|
class ViewState extends Equatable {
|
||||||
final Offset position;
|
final Offset position;
|
||||||
final double? scale;
|
final double? scale;
|
||||||
final Size? viewportSize;
|
final Size? viewportSize;
|
||||||
|
|
||||||
static const ViewState zero = ViewState(Offset.zero, 0, null);
|
static const ViewState zero = ViewState(Offset.zero, 0, null);
|
||||||
|
|
||||||
const ViewState(this.position, this.scale, this.viewportSize);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => '$runtimeType#${shortHash(this)}{position=$position, scale=$scale, viewportSize=$viewportSize}';
|
List<Object?> get props => [position, scale, viewportSize];
|
||||||
|
|
||||||
|
const ViewState(this.position, this.scale, this.viewportSize);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue