diff --git a/example/lib/main.dart b/example/lib/main.dart index bd5935d..9b01543 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -3,114 +3,100 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:open_earable_flutter/open_earable_flutter.dart'; +import 'widgets/frequency_player_widget.dart'; +import 'widgets/jingle_player_widget.dart'; +import 'widgets/rgb_led_control_widget.dart'; +import 'widgets/sensor_configuration_view.dart'; +import 'widgets/audio_player_control_widget.dart'; +import 'widgets/sensor_view.dart'; +import 'widgets/storage_path_audio_player_widget.dart'; +import 'widgets/grouped_box.dart'; + void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); + @override MyAppState createState() => MyAppState(); } class MyAppState extends State { - final OpenEarable _openEarable = OpenEarable(); + final WearableManager _wearableManager = WearableManager(); StreamSubscription? _scanSubscription; List discoveredDevices = []; - bool _connectedToEarable = false; - bool _waitingToConnect = false; - String? _deviceIdentifier; - String? _deviceFirmwareVersion; - - void _readDeviceInfo() async { - String? deviceIdentifier = - await _openEarable.bleManager.readDeviceIdentifier(); - String? deviceFirmwareVersion = - await _openEarable.bleManager.readDeviceFirmwareVersion(); - setState(() { - _deviceIdentifier = deviceIdentifier; - _deviceFirmwareVersion = deviceFirmwareVersion; - }); - } - @override - void initState() { - super.initState(); - _setupListeners(); - } - - void _setupListeners() async { - _openEarable.bleManager.connectionStateStream.listen((connectionState) { - if (connectionState) { - _readDeviceInfo(); - _writeSensorConfig(); - setState(() { - _waitingToConnect = false; - }); - } - setState(() { - _connectedToEarable = connectionState; - }); - }); - } + DiscoveredDevice? _connectingDevice; + Wearable? _connectedDevice; @override Widget build(BuildContext context) { + List? sensorViews; + List? sensorConfigurationViews; + if (_connectedDevice != null) { + sensorViews = SensorView.createSensorViews(_connectedDevice!); + sensorConfigurationViews = + SensorConfigurationView.createSensorConfigurationViews( + _connectedDevice!, + ); + } + return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Bluetooth Devices'), ), body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Padding( - padding: EdgeInsets.fromLTRB(33, 16, 0, 0), - child: Text( - "SCANNED DEVICES", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 12.0, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Padding( + padding: EdgeInsets.fromLTRB(33, 16, 0, 0), + child: Text( + "SCANNED DEVICES", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 12.0, + ), ), ), - ), - Visibility( + Visibility( visible: discoveredDevices.isNotEmpty, child: Container( - margin: const EdgeInsets.fromLTRB(16, 0, 16, 16), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all( - color: Colors.grey, - width: 1.0, - ), - borderRadius: BorderRadius.circular(8.0), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all( + color: Colors.grey, + width: 1.0, ), - child: ListView.builder( - padding: EdgeInsets.zero, - physics: - const NeverScrollableScrollPhysics(), // Disable scrolling, - shrinkWrap: true, - itemCount: discoveredDevices.length, - itemBuilder: (BuildContext context, int index) { - final device = discoveredDevices[index]; - return Column(children: [ - Material( - type: MaterialType.transparency, - child: ListTile( - textColor: Colors.black, - selectedTileColor: Colors.grey, - title: Text(device.name), - titleTextStyle: const TextStyle(fontSize: 16), - visualDensity: const VisualDensity( - horizontal: -4, vertical: -4), - trailing: _buildTrailingWidget(device.id), - onTap: () { - setState(() => _waitingToConnect = true); - _connectToDevice(device); - }, - )), + borderRadius: BorderRadius.circular(8.0), + ), + child: ListView.builder( + padding: EdgeInsets.zero, + physics: const NeverScrollableScrollPhysics(), + // Disable scrolling, + shrinkWrap: true, + itemCount: discoveredDevices.length, + itemBuilder: (BuildContext context, int index) { + final device = discoveredDevices[index]; + return Column( + children: [ + ListTile( + textColor: Colors.black, + selectedTileColor: Colors.grey, + title: Text(device.name), + titleTextStyle: const TextStyle(fontSize: 16), + visualDensity: const VisualDensity( + horizontal: -4, vertical: -4), + trailing: _buildTrailingWidget(device.id), + onTap: () { + _connectToDevice(device); + }, + ), if (index != discoveredDevices.length - 1) const Divider( height: 1.0, @@ -119,50 +105,149 @@ class MyAppState extends State { indent: 16.0, endIndent: 0.0, ), - ]); - }, - ))), - Visibility( - visible: _deviceIdentifier != null && _connectedToEarable, - child: Padding( - padding: const EdgeInsets.fromLTRB(33, 8, 0, 8), - child: Text( - "Connected to $_deviceIdentifier $_deviceFirmwareVersion", - style: const TextStyle(fontSize: 16), - ))), - Center( - child: ElevatedButton( - onPressed: _startScanning, - child: const Text('Restart Scan'), + ], + ); + }, + ), + ), + ), + Center( + child: ElevatedButton( + onPressed: _startScanning, + child: const Text('Restart Scan'), + ), ), - ) - ], + if (_connectedDevice != null) + GroupedBox( + title: "Device Info", + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Name: ${_connectedDevice?.name}", + ), + if (_connectedDevice is DeviceIdentifier) + FutureBuilder( + future: (_connectedDevice as DeviceIdentifier) + .readDeviceIdentifier(), + builder: (context, snapshot) { + return Text( + "Device Identifier: ${snapshot.data}", + ); + }, + ), + if (_connectedDevice is DeviceFirmwareVersion) + FutureBuilder( + future: (_connectedDevice as DeviceFirmwareVersion) + .readDeviceFirmwareVersion(), + builder: (context, snapshot) { + return Text( + "Firmware Version: ${snapshot.data}", + ); + }, + ), + if (_connectedDevice is DeviceHardwareVersion) + FutureBuilder( + future: (_connectedDevice as DeviceHardwareVersion) + .readDeviceHardwareVersion(), + builder: (context, snapshot) { + return Text( + "Hardware Version: ${snapshot.data}", + ); + }, + ), + ], + ), + ), + if (_connectedDevice is RgbLed) + GroupedBox( + title: "RGB LED", + child: + RgbLedControlWidget(rgbLed: _connectedDevice as RgbLed), + ), + if (_connectedDevice is FrequencyPlayer) + GroupedBox( + title: "Frequency Player", + child: FrequencyPlayerWidget( + frequencyPlayer: _connectedDevice as FrequencyPlayer, + ), + ), + if (_connectedDevice is JinglePlayer) + GroupedBox( + title: "Jingle Player", + child: JinglePlayerWidget( + jinglePlayer: _connectedDevice as JinglePlayer, + ), + ), + if (_connectedDevice is StoragePathAudioPlayer) + GroupedBox( + title: "Storage Path Audio Player", + child: StoragePathAudioPlayerWidget( + audioPlayer: _connectedDevice as StoragePathAudioPlayer, + ), + ), + if (_connectedDevice is AudioPlayerControls) + GroupedBox( + title: "Audio Player Controls", + child: AudioPlayerControlWidget( + audioPlayerControls: + _connectedDevice as AudioPlayerControls, + ), + ), + if (sensorConfigurationViews != null) + GroupedBox( + title: "Sensor Configurations", + child: Column( + children: sensorConfigurationViews, + ), + ), + if (sensorViews != null) + GroupedBox( + title: "Sensors", + child: Column( + children: sensorViews + .map((e) => Padding( + padding: const EdgeInsets.only( + bottom: 6.0, + top: 6.0, + ), + child: e, + )) + .toList(), + ), + ), + ] + .map((e) => Padding( + padding: const EdgeInsets.only( + bottom: 8.0, + top: 8.0, + ), + child: e, + )) + .toList(), + ), )), ), ); } Widget _buildTrailingWidget(String id) { - if (_openEarable.bleManager.connectedDevice?.id != id) { - return const SizedBox.shrink(); - } else if (_connectedToEarable) { + if (_connectedDevice?.deviceId == id) { return const Icon(size: 24, Icons.check, color: Colors.green); - } else if (_waitingToConnect) { + } else if (_connectingDevice?.id == id) { return const SizedBox( - height: 24, - width: 24, - child: CircularProgressIndicator(strokeWidth: 2)); + height: 24, + width: 24, + child: CircularProgressIndicator(strokeWidth: 2), + ); } return const SizedBox.shrink(); } void _startScanning() async { - discoveredDevices.removeWhere( - (device) => device.id != _openEarable.bleManager.connectedDevice?.id); - _openEarable.bleManager.startScan(); + _wearableManager.startScan(); _scanSubscription?.cancel(); - _scanSubscription = - _openEarable.bleManager.scanStream.listen((incomingDevice) { + _scanSubscription = _wearableManager.scanStream.listen((incomingDevice) { if (incomingDevice.name.isNotEmpty && !discoveredDevices.any((device) => device.id == incomingDevice.id)) { setState(() { @@ -173,14 +258,23 @@ class MyAppState extends State { } Future _connectToDevice(device) async { + setState(() { + _connectingDevice = device; + }); + _scanSubscription?.cancel(); - await _openEarable.bleManager.connectToDevice(device); - } + Wearable wearable = await _wearableManager.connectToDevice(device); + wearable.addDisconnectListener(() { + if (_connectedDevice?.deviceId == wearable.deviceId) { + setState(() { + _connectedDevice = null; + }); + } + }); - Future _writeSensorConfig() async { - OpenEarableSensorConfig config = - OpenEarableSensorConfig(sensorId: 3, samplingRate: 0, latency: 0); - _openEarable.sensorManager.writeSensorConfig(config); - //_openEarable.sensorManager.subscribeToSensorData(3); + setState(() { + _connectingDevice = null; + _connectedDevice = wearable; + }); } } diff --git a/example/lib/widgets/audio_player_control_widget.dart b/example/lib/widgets/audio_player_control_widget.dart new file mode 100644 index 0000000..12f7e3d --- /dev/null +++ b/example/lib/widgets/audio_player_control_widget.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:open_earable_flutter/open_earable_flutter.dart'; + +class AudioPlayerControlWidget extends StatelessWidget { + final AudioPlayerControls audioPlayerControls; + + const AudioPlayerControlWidget({Key? key, required this.audioPlayerControls}) + : super(key:key); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: audioPlayerControls.startAudio, + child: const Text('Start'), + ), + const SizedBox(width: 20), + ElevatedButton( + onPressed: audioPlayerControls.pauseAudio, + child: const Text('Pause'), + ), + const SizedBox(width: 20), + ElevatedButton( + onPressed: audioPlayerControls.stopAudio, + child: const Text('Stop'), + ), + ], + ); + } +} diff --git a/example/lib/widgets/frequency_player_widget.dart b/example/lib/widgets/frequency_player_widget.dart new file mode 100644 index 0000000..a4818ee --- /dev/null +++ b/example/lib/widgets/frequency_player_widget.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:open_earable_flutter/open_earable_flutter.dart'; + +class FrequencyPlayerWidget extends StatefulWidget { + final FrequencyPlayer frequencyPlayer; + + const FrequencyPlayerWidget({Key? key, required this.frequencyPlayer}) + : super(key:key); + + @override + State createState() => _FrequencyPlayerWidgetState(); +} + +class _FrequencyPlayerWidgetState extends State { + late WaveType _selectedWaveType; + double _frequency = 440.0; + double _loudness = 1.0; + + @override + void initState() { + super.initState(); + _selectedWaveType = widget.frequencyPlayer.supportedFrequencyPlayerWaveTypes.first; + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + DropdownButton( + value: _selectedWaveType, + items: widget.frequencyPlayer.supportedFrequencyPlayerWaveTypes + .map((waveType) { + return DropdownMenuItem( + value: waveType, + child: Text(waveType.toString()), + ); + }).toList(), + onChanged: (newValue) { + setState(() { + _selectedWaveType = newValue!; + }); + }, + ), + Expanded( + child: Column( + children: [ + Text('Frequency: ${_frequency.toStringAsFixed(0)} Hz'), + Slider( + value: _frequency, + min: 1.0, + max: 20000.0, + onChanged: (newValue) { + setState(() { + _frequency = newValue; + }); + }, + ), + ], + ), + ), + Column( + children: [ + Text('Loudness: ${(_loudness * 100).toStringAsFixed(0)}%'),Slider( + value: _loudness, + min: 0.0, + max: 1.0, + onChanged: (newValue) { + setState(() { + _loudness = newValue; + }); + }, + ), + ], + ), + ElevatedButton( + onPressed: () { + widget.frequencyPlayer.playFrequency( + _selectedWaveType, + frequency: _frequency, + loudness: _loudness, + ); + }, + child: const Text('Play'), + ), + ], + ); + } +} diff --git a/example/lib/widgets/grouped_box.dart b/example/lib/widgets/grouped_box.dart new file mode 100644 index 0000000..9861d9f --- /dev/null +++ b/example/lib/widgets/grouped_box.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; + +class GroupedBox extends StatelessWidget { + final String title; + final Widget child; + + const GroupedBox({ + Key? key, + required this.title, + required this.child, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Container( + width: double.maxFinite, + margin: const EdgeInsets.only(top: 8), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 4, + offset: Offset(2, 2), + ), + ], + ), + child: Padding( + padding: const EdgeInsets.only(top: 8), + child: child, + ), + ), + Positioned( + left: 16, + top: 0, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 8), + color: Colors.white, + child: Text( + title, + style: const TextStyle( + fontSize: 16, + ), + ), + ), + ), + ], + ); + } +} diff --git a/example/lib/widgets/jingle_player_widget.dart b/example/lib/widgets/jingle_player_widget.dart new file mode 100644 index 0000000..7ad817f --- /dev/null +++ b/example/lib/widgets/jingle_player_widget.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:open_earable_flutter/open_earable_flutter.dart'; + +class JinglePlayerWidget extends StatefulWidget { + final JinglePlayer jinglePlayer; + + const JinglePlayerWidget({Key? key, required this.jinglePlayer}) + : super(key:key); + + @override + State createState() => _JinglePlayerWidgetState(); +} + +class _JinglePlayerWidgetState extends State { + late Jingle _selectedJingle; + + @override + void initState() { + super.initState(); + _selectedJingle = widget.jinglePlayer.supportedJingles.first; + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + DropdownButton( + value: _selectedJingle, + items: widget.jinglePlayer.supportedJingles + .map((jingle) { + return DropdownMenuItem( + value: jingle, + child: Text(jingle.toString()), + ); + }).toList(), + onChanged: (newValue) { + setState(() { + _selectedJingle = newValue!; + }); + }, + ), + const SizedBox(width: 20), + ElevatedButton( + onPressed: () { + widget.jinglePlayer.playJingle(_selectedJingle); + }, + child: const Text('Play'), + ), + ], + ); + } +} diff --git a/example/lib/widgets/rgb_led_control_widget.dart b/example/lib/widgets/rgb_led_control_widget.dart new file mode 100644 index 0000000..20b614b --- /dev/null +++ b/example/lib/widgets/rgb_led_control_widget.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart'; +import 'package:open_earable_flutter/open_earable_flutter.dart'; + +class RgbLedControlWidget extends StatefulWidget { + final RgbLed rgbLed; + + const RgbLedControlWidget({Key? key, required this.rgbLed}) : super(key: key); + + @override + State createState() => _RgbLedControlWidgetState(); +} + +class _RgbLedControlWidgetState extends State { + Color _currentColor = Colors.black; + + void _showColorPickerDialog() { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Pick a color for the RGB LED'), + content: SingleChildScrollView( + child: ColorPicker( + pickerColor: _currentColor, + onColorChanged: (color) { + setState(() { + _currentColor = color; + }); + }, + pickerAreaHeightPercent: 0.8, + enableAlpha: false, + ), + ), + actions: [ + TextButton( + child: const Text('Done'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: _showColorPickerDialog, + style: ElevatedButton.styleFrom( + backgroundColor: _currentColor, + foregroundColor: _currentColor.computeLuminance() > 0.5 + ? Colors.black + : Colors.white, + ), + child: const Text('Choose Color'), + ), + const SizedBox(width: 20), + ElevatedButton( + onPressed: () { + widget.rgbLed.writeLedColor( + r: _currentColor.red, + g: _currentColor.green, + b: _currentColor.blue, + ); + }, + child: const Text('Set'), + ), + const SizedBox(width: 20), + ElevatedButton( + onPressed: () { + widget.rgbLed.writeLedColor(r: 0, g: 0, b: 0); + }, + child: const Text('Off'), + ), + ], + ); + } +} diff --git a/example/lib/widgets/sensor_configuration_view.dart b/example/lib/widgets/sensor_configuration_view.dart new file mode 100644 index 0000000..b59a818 --- /dev/null +++ b/example/lib/widgets/sensor_configuration_view.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:open_earable_flutter/open_earable_flutter.dart'; + +class SensorConfigurationView extends StatefulWidget { + final SensorConfiguration configuration; + + const SensorConfigurationView({Key? key, required this.configuration}) + : super(key: key); + + static List? createSensorConfigurationViews( + Wearable wearable) { + if (wearable is SensorManager) { + final sensorManager = wearable as SensorConfigurationManager; + return sensorManager.sensorConfigurations + .map( + (configuration) => SensorConfigurationView( + configuration: configuration, + ), + ) + .toList(); + } else { + return null; + } + } + + @override + State createState() => + _SensorConfigurationViewState(); +} + +class _SensorConfigurationViewState extends State { + SensorConfigurationValue? _selectedValue; + + @override + void initState() { + super.initState(); + _selectedValue = widget.configuration.values.first; + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.configuration.name, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + Row( + children: [ + DropdownButton( + value: _selectedValue, + items: widget.configuration.values.map((value) { + return DropdownMenuItem( + value: value, + child: Text(value.toString()), + ); + }).toList(), + onChanged: (newValue) { + setState(() { + _selectedValue = newValue; + }); + }, + ), + if (widget.configuration.unit != null) + Text(' ${widget.configuration.unit!}'), + const SizedBox(width: 16), + ElevatedButton( + onPressed: () { + if (_selectedValue != null) { + widget.configuration.setConfiguration(_selectedValue!); + } + }, + child: const Text('Set'), + ), + ], + ), + ], + ), + ); + } +} diff --git a/example/lib/widgets/sensor_view.dart b/example/lib/widgets/sensor_view.dart new file mode 100644 index 0000000..001ad0e --- /dev/null +++ b/example/lib/widgets/sensor_view.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:open_earable_flutter/open_earable_flutter.dart'; + +class SensorView extends StatelessWidget { + final Sensor sensor; + + const SensorView({Key? key, required this.sensor}) : super(key: key); + + static List? createSensorViews(Wearable wearable) { + if (wearable is SensorManager) { + final sensorManager = wearable as SensorManager; + return sensorManager.sensors + .map((sensor) => SensorView(sensor: sensor)) + .toList(); + } else { + return null; + } + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${sensor.chartTitle} (${sensor.sensorName}):', + style: const TextStyle(fontWeight: FontWeight.bold), + ), + Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 0, 0), + child: StreamBuilder( + stream: sensor.sensorStream, + builder: (context, snapshot) { + List renderedValues = []; + if (snapshot.hasData) { + final sensorValue = snapshot.data!; + renderedValues = sensorValue.values + .map((v) => v.toStringAsFixed(2).padLeft(7, ' ')) + .toList(); + } else { + renderedValues = List.generate( + sensor.axisCount, (_) => "#.##".padLeft(7, ' ')); + } + + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: List.generate(sensor.axisCount, (index) { + return Expanded( + child: Row( + children: [ + Text( + '${sensor.axisNames[index]}: ', + textAlign: TextAlign.left, + ), + Text( + '${renderedValues[index]} ${sensor.axisUnits[index]}', + textAlign: TextAlign.right, + ), + ], + ), + ); + }), + ); + }, + ), + ), + ], + ); + } +} diff --git a/example/lib/widgets/storage_path_audio_player_widget.dart b/example/lib/widgets/storage_path_audio_player_widget.dart new file mode 100644 index 0000000..8f924e0 --- /dev/null +++ b/example/lib/widgets/storage_path_audio_player_widget.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:open_earable_flutter/open_earable_flutter.dart'; + +class StoragePathAudioPlayerWidget extends StatefulWidget { + final StoragePathAudioPlayer audioPlayer; + + const StoragePathAudioPlayerWidget({Key? key, required this.audioPlayer}) + : super(key: key); + + @override + State createState() => + _StoragePathAudioPlayerWidgetState(); +} + +class _StoragePathAudioPlayerWidgetState + extends State { + final TextEditingController _textEditingController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: TextField( + controller: _textEditingController, + decoration: const InputDecoration( + hintText: 'Enter file path', + ), + ), + ), + ElevatedButton( + onPressed: () { + widget.audioPlayer + .playAudioFromStoragePath(_textEditingController.text); + }, + child: const Text('Play'), + ), + ], + ); + } + + @override + void dispose() { + _textEditingController.dispose(); + super.dispose(); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock index f7f2e1d..a6bbe60 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -102,6 +102,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_colorpicker: + dependency: "direct main" + description: + name: flutter_colorpicker + sha256: "969de5f6f9e2a570ac660fb7b501551451ea2a1ab9e2097e89475f60e07816ea" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter_lints: dependency: "direct dev" description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1886f56..9703840 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + flutter_colorpicker: ^1.1.0 dev_dependencies: flutter_test: