blob: c71f5eff6942d80a06f62bf9a58290bc1ac457b2 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:fidl_fuchsia_bluetooth/fidl.dart';
import 'package:fidl_fuchsia_bluetooth_le/fidl.dart' as ble;
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import '../manufacturer_names.dart';
import '../models/ble_scanner_model.dart';
// ignore_for_file: public_member_api_docs
/// Enum values to pass to Navigator.push()
enum DismissDialogAction {
/// Cancel the scan filter
cancel,
/// Apply the scan filter
save,
}
/// Widget that contains entry fields to build a BLE scan filter
class ScanFilterDialog extends StatefulWidget {
final BLEScannerModel moduleModel;
const ScanFilterDialog({@required this.moduleModel, Key key})
: super(key: key);
@override
_ScanFilterDialogState createState() => new _ScanFilterDialogState();
}
class _ScanFilterDialogState extends State<ScanFilterDialog> {
int _manufacturerId;
String _nameSubstring;
bool _connectable;
bool _saveNeeded = false;
final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
Future<bool> _onWillPop() async {
if (!_saveNeeded) {
return true;
}
final ThemeData theme = Theme.of(context);
final TextStyle dialogTextStyle =
theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color);
return await showDialog<bool>(
context: context,
builder: (BuildContext context) => new AlertDialog(
content:
new Text('Discard filters?', style: dialogTextStyle),
actions: <Widget>[
new FlatButton(
child: const Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop(false);
}),
new FlatButton(
child: const Text('DISCARD'),
onPressed: () {
Navigator.of(context).pop(true);
})
])) ??
false;
}
void _handleConnectableChanged(bool newValue) {
if (_connectable != newValue) {
setState(() {
_saveNeeded = true;
_connectable = newValue;
});
}
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return new Scaffold(
appBar: new AppBar(title: const Text('Scan Filters'), actions: <Widget>[
new FlatButton(
child: new Text('SAVE',
style: theme.textTheme.body1.copyWith(color: Colors.white)),
onPressed: () {
_formKey.currentState.save();
ble.ScanFilter filter = new ble.ScanFilter(
manufacturerIdentifier: _manufacturerId != null
? new UInt16(value: _manufacturerId)
: null,
nameSubstring: _nameSubstring?.isNotEmpty ?? false
? _nameSubstring
: null,
connectable: _connectable != null
? new Bool(value: _connectable)
: null,
);
widget.moduleModel.scanFilter = filter;
Navigator.pop(context, DismissDialogAction.save);
})
]),
body: new Form(
key: _formKey,
onWillPop: _onWillPop,
child: new Container(
padding: const EdgeInsets.all(36.0),
child: new Column(
children: <Widget>[
new ListTile(
title: const Text('Connectable'),
trailing: new Container(
width: 500.0,
child: new Column(
children: <Widget>[
new RadioListTile<bool>(
title: const Text('All'),
value: null,
groupValue: _connectable,
onChanged: _handleConnectableChanged),
new RadioListTile<bool>(
title: const Text('Connectable devices only'),
value: true,
groupValue: _connectable,
onChanged: _handleConnectableChanged),
new RadioListTile<bool>(
title:
const Text('Non-connectable devices only'),
value: false,
groupValue: _connectable,
onChanged: _handleConnectableChanged),
]
.map((Widget child) =>
new Expanded(child: child))
.toList()))),
new ListTile(
title: const Text('Manufacturer ID'),
trailing: new Container(
width: 500.0,
child: new DropdownButton<int>(
value: _manufacturerId,
onChanged: (int newValue) {
if (newValue != _manufacturerId) {
setState(() {
_saveNeeded = true;
_manufacturerId = newValue;
});
}
},
items:
<int>[null, 0x00E0, 0x004C].map((int value) {
return new DropdownMenuItem<int>(
value: value,
child: new Text(value == null
? 'None'
: getManufacturerName(value)),
);
}).toList()))),
new ListTile(
title: const Text('Name Substring'),
trailing: new Container(
width: 500.0,
child: new TextFormField(onSaved: (String newValue) {
if (newValue != _nameSubstring) {
setState(() {
_saveNeeded = true;
_nameSubstring = newValue;
});
}
})))
]
.map((Widget child) => new Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
child: child))
.toList()))));
}
}