"手写笔就是一个带压感的手指,没有特殊适配" — correct. The new editor fed RAW LINEAR stylus pressure into perfect_freehand, and the pressureGamma config (a slider in pen-settings) was read ONLY by that slider's UI and NEVER applied to a stroke. Dead wiring, like the rest. Wire it for real: - PenCanvas applies PressureCurve(floor, gamma) at capture, so stored pressure carries the feel and live + PDF export replay identically. - Natural defaults: gamma 0.7 (light touches register more width, rnote/ OneNote-like) + floor 0.12 (thin strokes keep body, not scratchy). - pen_editor threads PenConfig.pressureGamma into the canvas — the slider now actually changes stroke width. - pen_config: natural default + one-time migration of the legacy inert gamma 1.0, guarded by a marker so a deliberate 1.0 still sticks. Tests: pen_config_gamma_migration (4) + pressure_curve (6) pass; pen widget regressions green. flutter analyze: 0 issues. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
2.3 KiB
Dart
61 lines
2.3 KiB
Dart
// Proves the pen-feel pressure default and its one-time migration.
|
|
//
|
|
// Before this build pressureGamma was a dead slider (never applied to strokes),
|
|
// so a persisted 1.0 is the legacy inert default. load() upgrades that ONCE to
|
|
// the natural curve so the pen feels right out of the box — but the migration
|
|
// must not fight a user who later deliberately picks 1.0.
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import 'package:badnote/editor/input/pen_config.dart';
|
|
import 'package:badnote/editor/input/pressure_curve.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
test('fresh install defaults to the natural pressure curve', () async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
final c = await PenConfigController.load();
|
|
expect(c.value.pressureGamma, kNaturalPressureGamma);
|
|
expect(kNaturalPressureGamma, lessThan(1.0)); // sanity: it IS a soft curve
|
|
});
|
|
|
|
test('legacy stored gamma 1.0 migrates to the natural curve once', () async {
|
|
SharedPreferences.setMockInitialValues({
|
|
PenConfigController.prefsKey:
|
|
jsonEncode(const PenConfig(pressureGamma: 1.0).toJson()),
|
|
});
|
|
final c = await PenConfigController.load();
|
|
expect(c.value.pressureGamma, kNaturalPressureGamma,
|
|
reason: 'the dead-default 1.0 should be upgraded');
|
|
});
|
|
|
|
test('after migrating, a deliberate gamma 1.0 sticks (no re-migration)',
|
|
() async {
|
|
// First load migrates and sets the marker.
|
|
SharedPreferences.setMockInitialValues({
|
|
PenConfigController.prefsKey:
|
|
jsonEncode(const PenConfig(pressureGamma: 1.0).toJson()),
|
|
});
|
|
final first = await PenConfigController.load();
|
|
await first.setPressureGamma(1.0); // user deliberately chooses linear
|
|
|
|
// Reload: the marker is set, so 1.0 must be respected, not re-migrated.
|
|
final second = await PenConfigController.load();
|
|
expect(second.value.pressureGamma, 1.0,
|
|
reason: 'migration is one-time; user choice must persist');
|
|
});
|
|
|
|
test('a non-default stored gamma is never touched', () async {
|
|
SharedPreferences.setMockInitialValues({
|
|
PenConfigController.prefsKey:
|
|
jsonEncode(const PenConfig(pressureGamma: 0.5).toJson()),
|
|
});
|
|
final c = await PenConfigController.load();
|
|
expect(c.value.pressureGamma, 0.5);
|
|
});
|
|
}
|