From fc7a7800d519b6828b7b7f1f25bebf637cf79c05 Mon Sep 17 00:00:00 2001 From: AhmadHLB <44374418+AhmadHLB@users.noreply.github.com> Date: Thu, 9 May 2024 16:32:11 +0300 Subject: [PATCH] Changed new_transcription page Added Convert Screen Added dropdown to select instrument --- lib/pages/home/convert.dart | 128 +++++++++++ lib/pages/home/home.dart | 2 +- lib/pages/home/new_transcription.dart | 314 ++++---------------------- lib/pages/home/notation.dart | 43 +++- 4 files changed, 210 insertions(+), 277 deletions(-) create mode 100644 lib/pages/home/convert.dart diff --git a/lib/pages/home/convert.dart b/lib/pages/home/convert.dart new file mode 100644 index 000000000..f9c1c9d1b --- /dev/null +++ b/lib/pages/home/convert.dart @@ -0,0 +1,128 @@ +import 'package:flutter/material.dart'; + +class ConvertScreen extends StatefulWidget { + final String title; + + const ConvertScreen({ + Key? key, + required this.title, + }) : super(key: key); + + @override + State createState() => _ConvertScreenState(); +} + +class _ConvertScreenState extends State { + List items = ["Item 1", "Item 2", "Item 3","Item 4", "Item 5", "Item 6","Item 7", "Item 8", "Item 9"]; // Sample list of items + List selectedCheckboxes = []; + String? selectedRadio; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: Text(widget.title), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + "Convert", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + Expanded( + child: Card( + margin: EdgeInsets.only(bottom: 20), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: ListView.separated( + separatorBuilder: (context, index) => Visibility(visible: selectedRadio != items[index], child: const Divider()), + itemCount: items.length, + itemBuilder: (context, index) { + final item = items[index]; + return Visibility( + visible: selectedRadio != items[index], + child: SizedBox( + height: 40, + child: CheckboxListTile( + contentPadding: EdgeInsets.zero, // Remove extra padding + title: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Text(item), + ), + value: selectedCheckboxes.contains(item), + onChanged: (value) { + setState(() { + if (value != null && value) { + selectedCheckboxes.add(item); + } else { + selectedCheckboxes.remove(item); + } + }); + }, + ), + ), + ); + }, + ), + ), + ), + ), + const Divider(height: 10,), + const SizedBox(height: 10,), + const Text( + "To", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + Expanded( + child: Card( + margin: EdgeInsets.only(bottom: 20), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: ListView.separated( + + separatorBuilder: (context, index) => Visibility(visible: !selectedCheckboxes.contains(items[index]), child: const Divider()), + itemCount: items.length, + itemBuilder: (context, index) { + final item = items[index]; + return Visibility( + visible: !selectedCheckboxes.contains(items[index]), + child: SizedBox( + height: 40, + child: RadioListTile( + contentPadding: EdgeInsets.zero, + title: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Text(item), + ), + value: item, + groupValue: selectedRadio, + onChanged: (value) { + setState(() { + selectedRadio = value; + }); + }, + controlAffinity: ListTileControlAffinity.trailing, // Align radio buttons to the right + ), + ), + ); + }, + ), + ), + ), + + ), + + Center(child: TextButton(onPressed: Convert, child: const Text("Convert"))) + ], + ), + ), + ); + } + + void Convert() { + } +} diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index ee0eba9e7..991f54070 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -48,7 +48,7 @@ class _MyHomePageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => const NewTransScreenP1(), + builder: (context) => const NewTransScreen(), ), ); }, diff --git a/lib/pages/home/new_transcription.dart b/lib/pages/home/new_transcription.dart index d55980098..db0ca17ea 100644 --- a/lib/pages/home/new_transcription.dart +++ b/lib/pages/home/new_transcription.dart @@ -4,20 +4,22 @@ import 'package:file_picker/file_picker.dart'; import 'package:franz/components/audio_recorder.dart'; import 'package:franz/pages/home/home.dart'; -class NewTransScreenP1 extends StatefulWidget { - const NewTransScreenP1({super.key}); +class NewTransScreen extends StatefulWidget { + const NewTransScreen({super.key}); @override - State createState() => _NewTransScreenP1State(); + State createState() => _NewTransScreenP1State(); } -class _NewTransScreenP1State extends State { +class _NewTransScreenP1State extends State { String _mode = "Audio"; String _instrument = "Piano"; String _selectedFileName = ""; TextEditingController _ytlink = TextEditingController(); bool hasError = false; String? audioPath = ""; + final TextEditingController titleController = TextEditingController(); + final TextEditingController authorController = TextEditingController(); @override void initState() { @@ -61,23 +63,46 @@ class _NewTransScreenP1State extends State { }); } + void Transcribe() { + } + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, automaticallyImplyLeading: false, - title: const Text("Choose Source Type"), + title: const Text("Add a Transcription"), ), body: SingleChildScrollView( child: SizedBox( height: (MediaQuery.of(context).size.height - 75), - child: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ + Container( + margin: const EdgeInsets.only(top: 10, bottom: 10), + child: TextField( + controller: titleController, + decoration: const InputDecoration( + border: OutlineInputBorder(), + label: Text("Title"), + ), + ), + ), + Container( + margin: const EdgeInsets.only(top: 10, bottom: 10), + child: TextField( + controller: authorController, + decoration: const InputDecoration( + border: OutlineInputBorder(), + label: Text("Author"), + ), + ), + ), + const Divider(), RadioListTile( title: const Text('Audio File'), subtitle: @@ -167,7 +192,7 @@ class _NewTransScreenP1State extends State { maintainState: true, visible: _mode == "Record", child: Padding( - padding: EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16.0), child: Column( children: [ Visibility( @@ -192,7 +217,7 @@ class _NewTransScreenP1State extends State { children: [ Text(audioPath!.split('/').last), TextButton( - onPressed: _cancelRecord, child: Text("Cancel")) + onPressed: _cancelRecord, child: const Text("Cancel")) ], ), ), @@ -200,30 +225,26 @@ class _NewTransScreenP1State extends State { ), ), ), - if (hasError) const Text("Error: You need to select an audio", style: TextStyle(color: Colors.red),) else Text(''), - Spacer(), + if (hasError) const Text("Error: You need to select an audio source and input a title", style: TextStyle(color: Colors.red),) else Text(''), + const Spacer(), Row( children: [ TextButton( onPressed: () => Navigator.pop(context), - child: Text("Back")), - Spacer(), + child: const Text("Back")), + const Spacer(), TextButton( onPressed: () { - if ((audioPath != '') || (_ytlink.text != '') || (_selectedFileName != '')) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const NewTransScreenP2(), - ), - ); + if (((audioPath != '') || (_ytlink.text != '') || (_selectedFileName != '')) && (titleController.text != '')) { + Transcribe(); + Navigator.pop(context); } else { setState(() { hasError = true; }); } }, - child: Text("Next")) + child: const Text("Transcribe")) ], ) ], @@ -233,255 +254,4 @@ class _NewTransScreenP1State extends State { ), ); } -} - -class NewTransScreenP2 extends StatefulWidget { - const NewTransScreenP2({super.key}); - - @override - State createState() => _NewTransScreenP2State(); -} - -class _NewTransScreenP2State extends State { - List checked = List.generate(128, (index) => true); - List midiPrograms = [ - 'Acoustic Grand Piano', - 'Bright Acoustic Piano', - 'Electric Grand Piano', - 'Honky-tonk Piano', - 'Electric Piano 1', - 'Electric Piano 2', - 'Harpsichord', - 'Clavinet', - 'Celesta', - 'Glockenspiel', - 'Music Box', - 'Vibraphone', - 'Marimba', - 'Xylophone', - 'Tubular Bells', - 'Dulcimer', - 'Drawbar Organ', - 'Percussive Organ', - 'Rock Organ', - 'Church Organ', - 'Reed Organ', - 'Accordion', - 'Harmonica', - 'Tango Accordion', - 'Acoustic Guitar (nylon)', - 'Acoustic Guitar (steel)', - 'Electric Guitar (jazz)', - 'Electric Guitar (clean)', - 'Electric Guitar (muted)', - 'Overdriven Guitar', - 'Distortion Guitar', - 'Guitar Harmonics', - 'Acoustic Bass', - 'Electric Bass (finger)', - 'Electric Bass (pick)', - 'Fretless Bass', - 'Slap Bass 1', - 'Slap Bass 2', - 'Synth Bass 1', - 'Synth Bass 2', - 'Violin', - 'Viola', - 'Cello', - 'Contrabass', - 'Tremolo Strings', - 'Pizzicato Strings', - 'Orchestral Harp', - 'Timpani', - 'String Ensemble 1', - 'String Ensemble 2', - 'SynthStrings 1', - 'SynthStrings 2', - 'Choir Aahs', - 'Voice Oohs', - 'Synth Voice', - 'Orchestra Hit', - 'Trumpet', - 'Trombone', - 'Tuba', - 'Muted Trumpet', - 'French Horn', - 'Brass Section', - 'SynthBrass 1', - 'SynthBrass 2', - 'Soprano Sax', - 'Alto Sax', - 'Tenor Sax', - 'Baritone Sax', - 'Oboe', - 'English Horn', - 'Bassoon', - 'Clarinet', - 'Piccolo', - 'Flute', - 'Recorder', - 'Pan Flute', - 'Blown Bottle', - 'Shakuhachi', - 'Whistle', - 'Ocarina', - 'Lead 1 (square)', - 'Lead 2 (sawtooth)', - 'Lead 3 (calliope)', - 'Lead 4 (chiff)', - 'Lead 5 (charang)', - 'Lead 6 (voice)', - 'Lead 7 (fifths)', - 'Lead 8 (bass + lead)', - 'Pad 1 (new age)', - 'Pad 2 (warm)', - 'Pad 3 (polysynth)', - 'Pad 4 (choir)', - 'Pad 5 (bowed)', - 'Pad 6 (metallic)', - 'Pad 7 (halo)', - 'Pad 8 (sweep)', - 'FX 1 (rain)', - 'FX 2 (soundtrack)', - 'FX 3 (crystal)', - 'FX 4 (atmosphere)', - 'FX 5 (brightness)', - 'FX 6 (goblins)', - 'FX 7 (echoes)', - 'FX 8 (sci-fi)', - 'Sitar', - 'Banjo', - 'Shamisen', - 'Koto', - 'Kalimba', - 'Bag pipe', - 'Fiddle', - 'Shanai', - 'Tinkle Bell', - 'Agogo', - 'Steel Drums', - 'Woodblock', - 'Taiko Drum', - 'Melodic Tom', - 'Synth Drum', - 'Reverse Cymbal', - 'Guitar Fret Noise', - 'Breath Noise', - 'Seashore', - 'Bird Tweet', - 'Telephone Ring', - 'Helicopter', - 'Applause', - 'Gunshot' - ]; - bool allSelected = true; - String _searchValue = ""; - - @override - void initState() { - super.initState(); - } - - void selectAll(value) { - setState(() { - for (int i = 0; i < checked.length; i++) { - checked[i] = value; - } - }); - } - - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - automaticallyImplyLeading: false, - title: const Text("Pick Instruments"), - ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - children: [ - Expanded( - child: TextField( - decoration: InputDecoration( - suffixIcon: - Icon(Icons.search, color: Theme.of(context).primaryColor), - border: const OutlineInputBorder(), - label: const Text("Search Instrument"), - ), - onChanged: (value) { - setState(() { - _searchValue = value; - }); - }, - ), - - ), - Container( - margin: const EdgeInsets.only(right: 25), - child: Checkbox( - value: allSelected, - onChanged: (value) { - allSelected = value!; - selectAll(value); - }), - ), - ] - ), - Expanded( - child: Container( - margin: const EdgeInsets.only(top: 10, bottom: 20), - child: ListView.separated( - separatorBuilder: (context, index) => (midiPrograms[index].toLowerCase().contains(_searchValue.toLowerCase())) ? const Divider() : const SizedBox(), - itemCount: checked.length, - itemBuilder: (BuildContext context, int index) { - if(midiPrograms[index].toLowerCase().contains(_searchValue.toLowerCase())) { - return SizedBox( - height: 35, - child: CheckboxListTile( - title: Text(midiPrograms[index]), - value: checked[index], - onChanged: (bool? value) { - setState(() { - checked[index] = value!; - }); - - }, - ), - ); - } - else{ - return const SizedBox(); - } - }), - ), - ), - Row( - children: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text("Back")), - const Spacer(), - TextButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const MyHomePage(title: "Franz"), - ), - ); - }, - child: const Text("Transcribe")) - ], - ) - ], - ), - ), - ); - } -} +} \ No newline at end of file diff --git a/lib/pages/home/notation.dart b/lib/pages/home/notation.dart index 464622921..c4393b54e 100644 --- a/lib/pages/home/notation.dart +++ b/lib/pages/home/notation.dart @@ -1,8 +1,10 @@ import 'package:audioplayers/audioplayers.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_pdfview/flutter_pdfview.dart'; import 'package:franz/components/audio_player.dart'; import 'package:franz/services/api_service.dart'; +import 'package:franz/pages/home/convert.dart'; class SheetMusicViewerScreen extends StatefulWidget { final String link; @@ -25,10 +27,13 @@ class _SheetMusicViewerScreenState extends State { String errorMessage = ''; String _localFilePath = ""; AudioPlayer _audioPlayer = AudioPlayer(); + List instruments = ["Instrument 1", "Instrument 2", "Instrument 3", "Instrument 4", "Instrument 5", "Instrument 6", "Instrument 7", "Instrument 8", "Instrument 9", "Instrument 10", "Instrument 11", "Instrument 12", "Instrument 13", "Instrument 14", "Instrument 15", "Instrument 16", "Instrument 17", "Instrument 18"]; + String? selectedInstrument; @override void initState() { super.initState(); + selectedInstrument = instruments.first; ApiService().loadPDF(widget.link).then((value) { setState(() { _localFilePath = value; @@ -48,18 +53,48 @@ class _SheetMusicViewerScreenState extends State { child: Center( child: Column( children: [ - const Text("Sheet Music Viewer"), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(widget.link), + IconButton( + onPressed: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ConvertScreen(title: widget.title,), + ), + ), + icon: const Icon(Icons.swap_horiz) + ), + Expanded( + child: SingleChildScrollView( + child: DropdownButtonFormField( + decoration: const InputDecoration( + hintText: 'Select item', + border: OutlineInputBorder(), + ), + value: selectedInstrument, // Set the current selected item + onChanged: (String? value) { + setState(() { + selectedInstrument = value; // Update the selected item + }); + }, + items: instruments.map>((String item) { + return DropdownMenuItem( + value: item, + child: Text(item), + ); + }).toList(), + ), + ), + ), AudioPlayerButton( audioPlayer: _audioPlayer, - audioUrl: - "https://filesamples.com/samples/audio/mp3/sample2.mp3", + audioUrl: "https://filesamples.com/samples/audio/mp3/sample2.mp3", ), + ], ), + Text(errorMessage), Expanded( child: _localFilePath == ""