From 4a6155769c126f3a24d5e10c82f6349f2cc65ad7 Mon Sep 17 00:00:00 2001 From: minie4 Date: Sun, 25 Feb 2024 19:36:49 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20Start=20working=20on=20the=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add bottom NavBar - Add top bar - Start working on the `Mixing` Tab --- lib/main.dart | 114 ++++++++++++++++++++++++++++++++++++++++++ lib/mixing_card.dart | 63 +++++++++++++++++++++++ lib/mixing_tab.dart | 43 ++++++++++++++++ lib/ports_tab.dart | 35 +++++++++++++ lib/settings_tab.dart | 27 ++++++++++ 5 files changed, 282 insertions(+) create mode 100644 lib/main.dart create mode 100644 lib/mixing_card.dart create mode 100644 lib/mixing_tab.dart create mode 100644 lib/ports_tab.dart create mode 100644 lib/settings_tab.dart diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..7337e71 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,114 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:gomix_flutter/mixing_tab.dart'; +import 'package:gomix_flutter/ports_tab.dart'; +import 'package:gomix_flutter/settings_tab.dart'; + +void main() => runApp(const GoMixClient()); + +class GoMixClient extends StatelessWidget { + const GoMixClient({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + useMaterial3: true, + colorScheme: ColorScheme.fromSeed(seedColor: Colors.greenAccent), + sliderTheme: const SliderThemeData( + showValueIndicator: ShowValueIndicator.always, + ), + ), + // darkTheme: ThemeData( + // useMaterial3: true, + // colorScheme: ColorScheme.fromSeed( + // seedColor: Colors.greenAccent, brightness: Brightness.dark)), + home: const GoMixHome(), + ); + } +} + +class GoMixHome extends StatefulWidget { + const GoMixHome({super.key}); + + @override + State createState() => _GoMixHomeState(); +} + +class _GoMixHomeState extends State { + int currentPageIndex = 0; + + @override + Widget build(BuildContext context) { + final ThemeData theme = Theme.of(context); + return Scaffold( + bottomNavigationBar: NavigationBar( + onDestinationSelected: (int index) { + setState(() { + currentPageIndex = index; + }); + }, + selectedIndex: currentPageIndex, + indicatorColor: theme.colorScheme.secondaryContainer, + destinations: [ + NavigationDestination( + icon: Transform.rotate( + angle: 90 * pi / 180, child: const Icon(Icons.tune_outlined)), + label: 'Mixing', + ), + const NavigationDestination( + icon: Icon(Icons.settings_input_component_outlined), + label: 'Ports', + ), + const NavigationDestination( + icon: Icon(Icons.settings_outlined), + label: 'Settings', + ), + ], + ), + appBar: AppBar( + title: const Text('go-mix Audio Mixer'), + centerTitle: true, + leading: IconButton( + icon: const Icon(Icons.check_circle_outline), + color: theme.colorScheme.inversePrimary, + tooltip: 'Connected', + onPressed: () {}, + ), + actions: [ + Padding( + padding: const EdgeInsets.all(8), + child: IconButton( + icon: const Icon(Icons.supervised_user_circle_outlined), + tooltip: 'Select Server', + onPressed: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Next page'), + ), + body: const Center( + child: Text( + 'This is the next page', + style: TextStyle(fontSize: 24), + ), + ), + ); + }, + )); + }, + ), + ), + ], + ), + body: [ + const MixingTab(), + const PortsTab(), + const SettingsTab(), + ][currentPageIndex], + ); + } +} diff --git a/lib/mixing_card.dart b/lib/mixing_card.dart new file mode 100644 index 0000000..08f79b1 --- /dev/null +++ b/lib/mixing_card.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; + +class MixingCard extends StatefulWidget { + final String name; + const MixingCard({super.key, this.name = "Unknown"}); + + @override + State createState() => _MixingCardState(); +} + +class _MixingCardState extends State { + double _sliderValue = 0; + + @override + Widget build(BuildContext context) { + var labelStyle = Theme.of(context) + .textTheme + .labelLarge + ?.apply(color: Theme.of(context).colorScheme.primary); + return Card( + margin: const EdgeInsets.all(0), + shadowColor: Colors.transparent, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(left: 15, right: 15, top: 15), + child: Row( + children: [ + Expanded(child: Text(widget.name, style: labelStyle)), + IconButton.filledTonal( + isSelected: true, + onPressed: () {}, + icon: const Icon(Icons.mic_off_outlined)), + const SizedBox(width: 5), + IconButton.outlined( + isSelected: false, + onPressed: () {}, + icon: const Icon(Icons.unfold_more)) + ], + ), + ), + Transform.translate( + offset: Offset.fromDirection(0, 0), + child: SizedBox( + width: MediaQuery.of(context).size.width + 180, + child: Slider( + value: _sliderValue, + secondaryTrackValue: 1, + min: 0, + max: 4, + label: _sliderValue.toStringAsFixed(2), + onChanged: (val) { + setState(() { + _sliderValue = val; + }); + }), + ), + ), + ], + ), + ); + } +} diff --git a/lib/mixing_tab.dart b/lib/mixing_tab.dart new file mode 100644 index 0000000..7506823 --- /dev/null +++ b/lib/mixing_tab.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:gomix_flutter/mixing_card.dart'; + +class MixingTab extends StatefulWidget { + const MixingTab({super.key}); + + @override + State createState() => _MixingTabState(); +} + +class _MixingTabState extends State { + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + int cols = screenWidth > 550 ? 2 : 1; + int cardHeight = 110; + + return SizedBox.expand( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Inputs", style: Theme.of(context).textTheme.titleLarge), + const SizedBox(height: 10), + GridView.count( + shrinkWrap: true, + childAspectRatio: + (screenWidth - 32 - (10 * (cols - 1))) / cardHeight / cols, + crossAxisCount: cols, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + children: List.generate( + 6, (i) => MixingCard(name: "Port ${i.toString()}")), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/ports_tab.dart b/lib/ports_tab.dart new file mode 100644 index 0000000..2471ae3 --- /dev/null +++ b/lib/ports_tab.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +class PortsTab extends StatefulWidget { + const PortsTab({super.key}); + + @override + State createState() => _PortsTabState(); +} + +class _PortsTabState extends State { + @override + Widget build(BuildContext context) { + return const Padding( + padding: EdgeInsets.all(8.0), + child: Column( + children: [ + Card( + child: ListTile( + leading: Icon(Icons.mic_none), + title: Text('Port 1'), + subtitle: Text('...'), + ), + ), + Card( + child: ListTile( + leading: Icon(Icons.speaker_outlined), + title: Text('Port 2'), + subtitle: Text('...'), + ), + ), + ], + ), + ); + } +} diff --git a/lib/settings_tab.dart b/lib/settings_tab.dart new file mode 100644 index 0000000..3ba96fe --- /dev/null +++ b/lib/settings_tab.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +class SettingsTab extends StatefulWidget { + const SettingsTab({super.key}); + + @override + State createState() => _SettingsTabState(); +} + +class _SettingsTabState extends State { + @override + Widget build(BuildContext context) { + final ThemeData theme = Theme.of(context); + return Card( + shadowColor: Colors.transparent, + margin: const EdgeInsets.all(8.0), + child: SizedBox.expand( + child: Center( + child: Text( + 'Settings', + style: theme.textTheme.titleLarge, + ), + ), + ), + ); + } +}