diff --git a/lib/database.dart b/lib/database.dart index 48677be..1095850 100644 --- a/lib/database.dart +++ b/lib/database.dart @@ -20,7 +20,7 @@ class WorkModel { class PerformanceModel { final Person person; final Ensemble ensemble; - final Role role; + final Instrument role; PerformanceModel({ this.person, @@ -42,10 +42,11 @@ class Database extends _$Database { int get schemaVersion => 1; @override - MigrationStrategy get migration => - MigrationStrategy(beforeOpen: (details) async { - await customStatement('PRAGMA foreign_keys = ON'); - }); + MigrationStrategy get migration => MigrationStrategy( + beforeOpen: (details) async { + await customStatement('PRAGMA foreign_keys = ON'); + }, + ); Future updatePerson(Person person) async { await into(persons).insert(person, orReplace: true); @@ -82,10 +83,6 @@ class Database extends _$Database { await into(ensembles).insert(ensemble, orReplace: true); } - Future updateRole(Role role) async { - await into(roles).insert(role, orReplace: true); - } - Future updateRecording( Recording recording, List models) async { await transaction(() async { diff --git a/lib/database.moor b/lib/database.moor index 2a6e327..690b44f 100644 --- a/lib/database.moor +++ b/lib/database.moor @@ -4,6 +4,8 @@ CREATE TABLE persons ( last_name TEXT NOT NULL ); +-- This represents real instruments as well as other roles that can be played +-- in a recording. CREATE TABLE instruments ( id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL @@ -28,11 +30,6 @@ CREATE TABLE ensembles ( name TEXT NOT NULL ); -CREATE TABLE roles ( - id INTEGER NOT NULL PRIMARY KEY, - name TEXT NOT NULL -); - CREATE TABLE recordings ( id INTEGER NOT NULL PRIMARY KEY, work INTEGER REFERENCES works(id) @@ -42,7 +39,7 @@ CREATE TABLE performances ( recording INTEGER NOT NULL REFERENCES recordings(id) ON DELETE CASCADE, person INTEGER REFERENCES persons(id) ON DELETE CASCADE, ensemble INTEGER REFERENCES ensembles(id) ON DELETE CASCADE, - role INTEGER REFERENCES roles(id) + role INTEGER REFERENCES instruments(id) ); allPersons: @@ -84,12 +81,6 @@ SELECT * FROM ensembles ORDER BY name; ensembleById: SELECT * FROM ensembles WHERE id = :id LIMIT 1; -allRoles: -SELECT * FROM roles ORDER BY name; - -roleById: -SELECT * FROM roles WHERE id = :id LIMIT 1; - recordingById: SELECT * FROM recordings WHERE id = :id; diff --git a/lib/editors/instrument.dart b/lib/editors/instrument.dart index 8777415..b2aedc6 100644 --- a/lib/editors/instrument.dart +++ b/lib/editors/instrument.dart @@ -32,7 +32,7 @@ class _InstrumentEditorState extends State { return Scaffold( appBar: AppBar( - title: Text('Instrument'), + title: Text('Instrument/Role'), actions: [ FlatButton( child: Text('DONE'), diff --git a/lib/editors/role.dart b/lib/editors/role.dart deleted file mode 100644 index 24b67de..0000000 --- a/lib/editors/role.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../backend.dart'; -import '../database.dart'; - -class RoleEditor extends StatefulWidget { - final Role role; - - RoleEditor({ - this.role, - }); - - @override - _RoleEditorState createState() => _RoleEditorState(); -} - -class _RoleEditorState extends State { - final nameController = TextEditingController(); - - @override - void initState() { - super.initState(); - - if (widget.role != null) { - nameController.text = widget.role.name; - } - } - - @override - Widget build(BuildContext context) { - final backend = Backend.of(context); - - return Scaffold( - appBar: AppBar( - title: Text('Role'), - actions: [ - FlatButton( - child: Text('DONE'), - onPressed: () async { - final role = Role( - id: widget.role?.id ?? generateId(), - name: nameController.text, - ); - - await backend.db.updateRole(role); - Navigator.pop(context, role); - }, - ) - ], - ), - body: ListView( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: TextField( - controller: nameController, - decoration: InputDecoration( - labelText: 'Name', - ), - ), - ), - ], - ), - ); - } -} diff --git a/lib/editors/work.dart b/lib/editors/work.dart index 523233f..f9ce830 100644 --- a/lib/editors/work.dart +++ b/lib/editors/work.dart @@ -89,6 +89,7 @@ class WorkProperties extends StatelessWidget { context, MaterialPageRoute( builder: (context) => InstrumentsSelector( + multiple: true, selection: instruments, ), fullscreenDialog: true, diff --git a/lib/selectors/instruments.dart b/lib/selectors/instruments.dart index eb960bf..23cfba7 100644 --- a/lib/selectors/instruments.dart +++ b/lib/selectors/instruments.dart @@ -5,9 +5,11 @@ import '../database.dart'; import '../editors/instrument.dart'; class InstrumentsSelector extends StatefulWidget { + final bool multiple; final List selection; InstrumentsSelector({ + this.multiple = false, this.selection, }); @@ -33,13 +35,15 @@ class _InstrumentsSelectorState extends State { return Scaffold( appBar: AppBar( - title: Text('Select instruments'), - actions: [ - FlatButton( - child: Text('DONE'), - onPressed: () => Navigator.pop(context, selection.toList()), - ), - ], + title: Text(widget.multiple ? 'Select instruments/roles' : 'Select instrument/role'), + actions: widget.multiple + ? [ + FlatButton( + child: Text('DONE'), + onPressed: () => Navigator.pop(context, selection.toList()), + ), + ] + : null, ), body: StreamBuilder( stream: backend.db.allInstruments().watch(), @@ -50,20 +54,27 @@ class _InstrumentsSelectorState extends State { itemBuilder: (context, index) { final instrument = snapshot.data[index]; - return CheckboxListTile( - title: Text(instrument.name), - value: selection.contains(instrument), - checkColor: Colors.black, - onChanged: (selected) { - setState(() { - if (selected) { - selection.add(instrument); - } else { - selection.remove(instrument); - } - }); - }, - ); + if (widget.multiple) { + return CheckboxListTile( + title: Text(instrument.name), + value: selection.contains(instrument), + checkColor: Colors.black, + onChanged: (selected) { + setState(() { + if (selected) { + selection.add(instrument); + } else { + selection.remove(instrument); + } + }); + }, + ); + } else { + return ListTile( + title: Text(instrument.name), + onTap: () => Navigator.pop(context, instrument), + ); + } }, ); } else { @@ -82,9 +93,13 @@ class _InstrumentsSelectorState extends State { )); if (instrument != null) { - setState(() { - selection.add(instrument); - }); + if (widget.multiple) { + setState(() { + selection.add(instrument); + }); + } else { + Navigator.pop(context, instrument); + } } }, ), diff --git a/lib/selectors/performer.dart b/lib/selectors/performer.dart index b1c3215..b68f44e 100644 --- a/lib/selectors/performer.dart +++ b/lib/selectors/performer.dart @@ -3,17 +3,17 @@ import 'package:flutter/material.dart'; import '../backend.dart'; import '../database.dart'; import '../editors/person.dart'; -import '../selectors/role.dart'; + +import 'instruments.dart'; // TODO: Allow selecting and adding ensembles. -// TODO: Allow selecting instruments as roles. class PerformerSelector extends StatefulWidget { @override _PerformerSelectorState createState() => _PerformerSelectorState(); } class _PerformerSelectorState extends State { - Role role; + Instrument role; Person person; @override @@ -41,9 +41,9 @@ class _PerformerSelectorState extends State { Material( elevation: 2.0, child: ListTile( - title: Text('Role'), + title: Text('Instrument/Role'), subtitle: - Text(role != null ? role.name : 'Select role or instrument'), + Text(role != null ? role.name : 'Select instrument/role'), trailing: IconButton( icon: const Icon(Icons.delete), onPressed: () { @@ -53,10 +53,10 @@ class _PerformerSelectorState extends State { }, ), onTap: () async { - final Role newRole = await Navigator.push( + final Instrument newRole = await Navigator.push( context, MaterialPageRoute( - builder: (context) => RoleSelector(), + builder: (context) => InstrumentsSelector(), fullscreenDialog: true, )); diff --git a/lib/selectors/role.dart b/lib/selectors/role.dart deleted file mode 100644 index 952a10a..0000000 --- a/lib/selectors/role.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../backend.dart'; -import '../database.dart'; -import '../editors/role.dart'; - -class RoleSelector extends StatelessWidget { - @override - Widget build(BuildContext context) { - final backend = Backend.of(context); - - return Scaffold( - appBar: AppBar( - title: Text('Select role'), - ), - body: StreamBuilder>( - stream: backend.db.allRoles().watch(), - builder: (context, snapshot) { - if (snapshot.hasData) { - return ListView.builder( - itemCount: snapshot.data.length, - itemBuilder: (context, index) { - final role = snapshot.data[index]; - - return ListTile( - title: Text(role.name), - onTap: () => Navigator.pop(context, role), - ); - }, - ); - } else { - return Container(); - } - }, - ), - floatingActionButton: FloatingActionButton( - child: const Icon(Icons.add), - onPressed: () async { - final Role role = await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => RoleEditor(), - fullscreenDialog: true, - )); - - if (role != null) { - Navigator.pop(context, role); - } - }, - ), - ); - } -}