From 73b975894465d57895a85569f08929090e1df40c Mon Sep 17 00:00:00 2001 From: phamconganh Date: Sat, 1 Jun 2024 22:45:54 +0700 Subject: [PATCH] add note on,off --- lib/src/interactive_piano.dart | 69 ++++++++++++++++++++++++---------- pubspec.lock | 68 ++++++++++++++++++++++----------- pubspec.yaml | 6 +-- 3 files changed, 98 insertions(+), 45 deletions(-) diff --git a/lib/src/interactive_piano.dart b/lib/src/interactive_piano.dart index f756944..5eb21f4 100644 --- a/lib/src/interactive_piano.dart +++ b/lib/src/interactive_piano.dart @@ -6,6 +6,8 @@ import 'note_position.dart'; import 'note_range.dart'; typedef OnNotePositionTapped = void Function(NotePosition position); +typedef OnNoteOn = void Function(TapDownDetails details, NotePosition position); +typedef OnNoteOff = void Function(TapUpDetails details, NotePosition position); /// Renders a scrollable interactive piano. class InteractivePiano extends StatefulWidget { @@ -42,6 +44,12 @@ class InteractivePiano extends StatefulWidget { /// Callback for interacting with piano keys. final OnNotePositionTapped? onNotePositionTapped; + /// Callback for interacting with piano keys note on. + final OnNoteOn? onNoteOn; + + /// Callback for interacting with piano keys note off. + final OnNoteOff? onNoteOff; + /// Set and change at any time (i.e. with `setState`) to cause the piano to scroll so that the desired note is centered. final NotePosition? noteToScrollTo; @@ -77,6 +85,8 @@ class InteractivePiano extends StatefulWidget { this.hideNoteNames = false, this.hideScrollbar = false, this.onNotePositionTapped, + this.onNoteOn, + this.onNoteOff, this.noteToScrollTo, this.keyWidth}) : super(key: key); @@ -194,18 +204,22 @@ class _InteractivePianoState extends State { Row( children: naturals .map((note) => _PianoKey( - notePosition: note, - color: widget.naturalColor, - hideNoteName: widget.hideNoteNames, - isAnimated: widget - .animateHighlightedNotes && - widget.highlightedNotes.contains(note), - highlightColor: - widget.highlightedNotes.contains(note) - ? widget.highlightColor - : null, - keyWidth: _lastKeyWidth, - onTap: _onNoteTapped(note))) + notePosition: note, + color: widget.naturalColor, + hideNoteName: widget.hideNoteNames, + isAnimated: + widget.animateHighlightedNotes && + widget.highlightedNotes + .contains(note), + highlightColor: + widget.highlightedNotes.contains(note) + ? widget.highlightColor + : null, + keyWidth: _lastKeyWidth, + onTap: _onNoteTapped(note), + onTapDown: _onNoteOn(note), + onTapUp: _onNoteOff(note), + )) .toList(), ), Positioned( @@ -234,6 +248,8 @@ class _InteractivePianoState extends State { : null, keyWidth: _lastKeyWidth, onTap: _onNoteTapped(note), + onTapDown: _onNoteOn(note), + onTapUp: _onNoteOff(note), ), ) .toList(), @@ -248,7 +264,19 @@ class _InteractivePianoState extends State { void Function()? _onNoteTapped(NotePosition notePosition) => widget.onNotePositionTapped == null ? null - : () => widget.onNotePositionTapped!(notePosition); + : () => widget.onNotePositionTapped!.call(notePosition); + + GestureTapDownCallback? _onNoteOn(NotePosition notePosition) => + widget.onNoteOn == null + ? null + : (TapDownDetails details) => + widget.onNoteOn!.call(details, notePosition); + + GestureTapUpCallback? _onNoteOff(NotePosition notePosition) => + widget.onNoteOff == null + ? null + : (TapUpDetails details) => + widget.onNoteOff!.call(details, notePosition); } class _PianoKey extends StatefulWidget { @@ -257,6 +285,8 @@ class _PianoKey extends StatefulWidget { final BorderRadius _borderRadius; final bool hideNoteName; final VoidCallback? onTap; + final GestureTapDownCallback? onTapDown; + final GestureTapUpCallback? onTapUp; final bool isAnimated; final Color _color; @@ -266,7 +296,9 @@ class _PianoKey extends StatefulWidget { required this.notePosition, required this.keyWidth, required this.hideNoteName, - required this.onTap, + this.onTap, + this.onTapDown, + this.onTapUp, required this.isAnimated, required Color color, Color? highlightColor, @@ -365,11 +397,8 @@ class __PianoKeyState extends State<_PianoKey> borderRadius: widget._borderRadius, highlightColor: Colors.grey, onTap: widget.onTap == null ? null : () {}, - onTapDown: widget.onTap == null - ? null - : (_) { - widget.onTap!(); - }, + onTapDown: widget.onTapDown, + onTapUp: widget.onTapUp, ))), Positioned( left: 0.0, @@ -393,7 +422,7 @@ class __PianoKeyState extends State<_PianoKey> child: Text( widget.notePosition.name, textAlign: TextAlign.center, - textScaleFactor: 1.0, + textScaler: TextScaler.linear(1.0), style: TextStyle( fontSize: widget.keyWidth / 3.5, color: widget.notePosition.accidental == diff --git a/pubspec.lock b/pubspec.lock index 45e6da1..ea3122b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -181,10 +181,10 @@ packages: dependency: "direct main" description: name: equatable - sha256: "8867afc0f09dd9aff976817fbd94e9a35a3a2e58bef3b39a5376918321ec97a4" + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.5" fake_async: dependency: transitive description: @@ -299,6 +299,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + url: "https://pub.dev" + source: hosted + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" logging: dependency: transitive description: @@ -311,26 +335,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.12.0" mime: dependency: transitive description: @@ -351,10 +375,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" pedantic: dependency: transitive description: @@ -468,10 +492,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" timing: dependency: transitive description: @@ -496,22 +520,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - watcher: + vm_service: dependency: transitive description: - name: watcher - sha256: "68173f2fa67d241323a4123be7ed4e43424c54befa5505d71c8ad4b7baf8f71d" + name: vm_service + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "1.0.0" - web: + version: "14.2.1" + watcher: dependency: transitive description: - name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + name: watcher + sha256: "68173f2fa67d241323a4123be7ed4e43424c54befa5505d71c8ad4b7baf8f71d" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "1.0.0" web_socket_channel: dependency: transitive description: @@ -529,5 +553,5 @@ packages: source: hosted version: "3.1.0" sdks: - dart: ">=3.2.0-194.0.dev <3.13.5" - flutter: ">=3.3.10" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 10ad656..f9bab40 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,11 +1,11 @@ name: piano description: Utilities and widgets for working with piano sheet music learning. -version: 1.0.4 +version: 1.0.4+1 homepage: https://www.handform.net repository: https://github.com/craigomac/piano environment: - sdk: ">=3.0.0 <3.13.5" + sdk: ">=3.0.0 <4.0.0" flutter: ">=3.3.10" dependencies: @@ -17,7 +17,7 @@ dependencies: dev_dependencies: build_runner: ^2.4.8 - freezed: 2.4.6 + freezed: ^2.4.6 flutter_test: sdk: flutter