fix: PDF finger ink, chrome UX, OneNote pens, and pen physics
Some checks failed
CI / Windows build (push) Has been cancelled

Wire finger drawing on PDF without breaking pinch; auto-hide page scrubber and fix bounce; share sticky tools with resize and per-page remember; side-button select; separate pen slots with colors; rnote pressure shapes plus tip-velocity width and lower stroke latency.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-06 16:01:01 +08:00
parent 85af037b7d
commit f31dd0fb52
17 changed files with 835 additions and 234 deletions

View File

@@ -1,6 +1,25 @@
import 'package:flutter/material.dart';
import '../input/pen_config.dart';
import '../input/pressure_curve.dart';
String _shapeNameForGamma(double gamma) {
if ((gamma - 0.6).abs() < 0.05) return 'soft';
if ((gamma - 1.0).abs() < 0.05) return 'linear';
if ((gamma - 2.0).abs() < 0.05) return 'quadratic';
if ((gamma - 3.0).abs() < 0.05) return 'cubic';
if ((gamma - 0.5).abs() < 0.05) return 'sqrt';
return 'soft';
}
PressureCurve _curveForName(String name) => switch (name) {
'linear' => PressureCurve.shaped(PressureCurveShape.linear),
'quadratic' => PressureCurve.shaped(PressureCurveShape.quadratic),
'cubic' => PressureCurve.shaped(PressureCurveShape.cubic),
'sqrt' => PressureCurve.shaped(PressureCurveShape.sqrt),
'logarithmic' => PressureCurve.shaped(PressureCurveShape.soft), // gamma proxy
_ => PressureCurve.shaped(PressureCurveShape.soft),
};
/// Shows a Material You modal bottom sheet for configuring pen input.
///
@@ -111,6 +130,32 @@ class _PenSettingsSheet extends StatelessWidget {
formatValue: (v) => v.toStringAsFixed(2),
onChanged: controller.setPressureGamma,
),
_LabeledRow(
label: 'Curve Preset (rnote)',
child: DropdownMenu<String>(
initialSelection: _shapeNameForGamma(config.pressureGamma),
onSelected: (name) {
if (name == null) return;
final shaped = _curveForName(name);
controller.setPressureGamma(shaped.gamma);
},
dropdownMenuEntries: const [
DropdownMenuEntry(value: 'soft', label: 'Soft (γ≈0.6)'),
DropdownMenuEntry(value: 'linear', label: 'Linear'),
DropdownMenuEntry(
value: 'quadratic', label: 'Quadratic / Pow2'),
DropdownMenuEntry(value: 'cubic', label: 'Cubic'),
DropdownMenuEntry(value: 'sqrt', label: 'Sqrt (pencil)'),
],
),
),
const Padding(
padding: EdgeInsets.only(left: 8, bottom: 8),
child: Text(
'笔刷自带曲线优先(钢笔=二次/Pow2铅笔=平方根)。全局 gamma 作后备。',
style: TextStyle(fontSize: 12),
),
),
// ── Input ─────────────────────────────────────────────────
_SectionHeader(
@@ -265,12 +310,13 @@ class _ActionDropdown extends StatelessWidget {
final ValueChanged<PenButtonAction> onChanged;
static String _label(PenButtonAction action) => switch (action) {
PenButtonAction.none => 'None',
PenButtonAction.eraser => 'Eraser',
PenButtonAction.undo => 'Undo',
PenButtonAction.toggleTool => 'Toggle Tool',
PenButtonAction.pan => 'Pan',
PenButtonAction.selectText => 'Select text',
PenButtonAction.none => '',
PenButtonAction.eraser => '橡皮',
PenButtonAction.undo => '撤销',
PenButtonAction.toggleTool => '切换工具',
PenButtonAction.pan => '平移',
PenButtonAction.select => '选择(笔迹)',
PenButtonAction.selectText => '选择文本',
};
@override