diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 8d4492f..9625e10 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 11.0 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index deb66de..6b8f839 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -127,7 +127,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -171,10 +171,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -185,6 +187,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -272,7 +275,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -346,7 +349,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -395,7 +398,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3db53b6..b52b2e6 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ CADisableMinimumFrameDurationOnPhone + UIApplicationSupportsIndirectInputEvents + diff --git a/example/lib/main.dart b/example/lib/main.dart index 1e6665d..f071f1b 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -172,6 +172,23 @@ class _HomePageState extends State { [Am]As we lose our, [G]inhibition [C]Celebration, [F]its around us [Am]Every nation, [G]all around us +{soc} +[C]Singing forever [F]young, +Singing [Am]songs underneath the sun[G] +Let's [C]rejoice in the beautiful game[F] +And [Am]together, every end of the day[G] +{eoc} +[C]When I get older, [F]I will be stronger +[Am]They'll call me freedom, [G]just like a waving [C]flag +And then it goes [F]back, and then it goes [Am]back +And then it goes [G]back , and then it goes … +{soc} +We all say +[C]When I get older, [F]I will be stronger +[Am]They'll call me freedom, [G]just like a waving [C]flag +And then it goes [F]back, and then it goes [Am]back +And then it goes [G]back , and then it goes … +{eoc} '''; } } diff --git a/lib/src/chord_parser.dart b/lib/src/chord_parser.dart index c52d064..4545840 100644 --- a/lib/src/chord_parser.dart +++ b/lib/src/chord_parser.dart @@ -21,6 +21,7 @@ class ChordProcessor { required String text, required TextStyle lyricsStyle, required TextStyle chordStyle, + required TextStyle chorusStyle, double scaleFactor = 1.0, int widgetPadding = 0, int transposeIncrement = 0, @@ -58,7 +59,7 @@ class ChordProcessor { List _chordLyricsLines = newLines .map( - (line) => _processLine(line, lyricsStyle, chordStyle)) + (line) => _processLine(line, lyricsStyle, chordStyle, chorusStyle)) .toList(); return ChordLyricsDocument(_chordLyricsLines, @@ -125,15 +126,23 @@ class ChordProcessor { .width; } - ChordLyricsLine _processLine( - String line, TextStyle lyricsStyle, TextStyle chordStyle) { + bool isChorus = false; + ChordLyricsLine _processLine(String line, TextStyle lyricsStyle, + TextStyle chordStyle, TextStyle chorusStyle) { ChordLyricsLine _chordLyricsLine = ChordLyricsLine(); String _lyricsSoFar = ''; String _chordsSoFar = ''; bool _chordHasStarted = false; + if (line.contains("{soc}") || line.contains("{start_of_chorus}")) { + isChorus = true; + } else if (line.contains("{eoc}") || line.contains("{end_of_chorus}")) { + isChorus = false; + } line.split('').forEach((character) { if (character == ']') { - final sizeOfLeadingLyrics = textWidth(_lyricsSoFar, lyricsStyle); + final sizeOfLeadingLyrics = isChorus + ? textWidth(_lyricsSoFar, chorusStyle) + : textWidth(_lyricsSoFar, lyricsStyle); final lastChordText = _chordLyricsLine.chords.isNotEmpty ? _chordLyricsLine.chords.last.chordText diff --git a/lib/src/lyrics_renderer.dart b/lib/src/lyrics_renderer.dart index 86b74d1..071ca66 100644 --- a/lib/src/lyrics_renderer.dart +++ b/lib/src/lyrics_renderer.dart @@ -128,6 +128,7 @@ class _LyricsRendererState extends State { text: widget.lyrics, lyricsStyle: widget.textStyle, chordStyle: widget.chordStyle, + chorusStyle: chorusStyle, widgetPadding: widget.widgetPadding, scaleFactor: widget.scaleFactor, transposeIncrement: widget.transposeIncrement, diff --git a/test/chord_processor_test.dart b/test/chord_processor_test.dart index 2c9f9a5..f1f3bdb 100644 --- a/test/chord_processor_test.dart +++ b/test/chord_processor_test.dart @@ -15,6 +15,7 @@ void main() { text: text, lyricsStyle: textStyle, chordStyle: textStyle, + chorusStyle: textStyle, ); expect( @@ -58,19 +59,22 @@ void main() { MaterialApp( builder: (context, _) { String text = - '[C]This is t[D]he lyrics[E]\n[A]This is t[D]he se[B]cond line[E]'; + '{soc}\n[C]This is t[D]he Cho[D]rus\n{eoc}\n[C]This is t[D]he lyrics[E]\n[A]This is t[D]he se[B]cond line[E]'; final textStyle = TextStyle(fontSize: 18, color: Colors.green); + final chorusStyle = TextStyle( + fontSize: 21, fontWeight: FontWeight.bold, color: Colors.white); final processor = ChordProcessor(context); final chordDocument = processor.processText( text: text, lyricsStyle: textStyle, chordStyle: textStyle, + chorusStyle: chorusStyle, ); expect( chordDocument.chordLyricsLines.length, - 2, + 5, ); expect( chordDocument.chordLyricsLines.last.chords.length, @@ -81,23 +85,27 @@ void main() { 'E', ); expect( - chordDocument.chordLyricsLines.first.chords.first.leadingSpace, + chordDocument.chordLyricsLines[1].chords.first.leadingSpace, 0.0, ); - expect( - chordDocument.chordLyricsLines.first.chords[1].chordText, + chordDocument.chordLyricsLines[1].chords[1].chordText, 'D', ); final textWidth = processor.textWidth('This is t', textStyle); final chordWidth = processor.textWidth('C', textStyle); expect( - chordDocument.chordLyricsLines.first.chords[1].leadingSpace, + chordDocument.chordLyricsLines[3].chords[1].leadingSpace, textWidth - chordWidth, ); - // The builder function must return a widget. + final chorusTextWidth = processor.textWidth('This is t', chorusStyle); + final chorusChordWidth = processor.textWidth('C', textStyle); + expect( + chordDocument.chordLyricsLines[1].chords[1].leadingSpace, + chorusTextWidth - chorusChordWidth, + ); // The builder function must return a widget. return Container(); }, ), @@ -118,6 +126,7 @@ void main() { text: text, lyricsStyle: textStyle, chordStyle: textStyle, + chorusStyle: textStyle, ); expect(chordDocument.capo, 3); @@ -174,6 +183,7 @@ void main() { text: text, lyricsStyle: textStyle, chordStyle: textStyle, + chorusStyle: textStyle, ); expect(