| // Copyright 2015 The Vanadium 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 '../logic/croupier.dart' as logic_croupier; |
| import '../logic/croupier_settings.dart' show CroupierSettings, RandomSettings; |
| |
| import 'package:sky/widgets.dart'; |
| |
| typedef void NoArgCb(); |
| typedef void OneStringCb(String data); |
| |
| enum DialogType { Text, ColorPicker, ImagePicker } |
| |
| const String nameKey = "name"; |
| const String colorKey = "color"; |
| const String avatarKey = "avatar"; |
| |
| Map<String, GlobalKey> globalKeys = { |
| nameKey: new GlobalKey(), |
| colorKey: new GlobalKey(), |
| avatarKey: new GlobalKey() |
| }; |
| |
| Map<String, DialogType> dialogTypes = { |
| nameKey: DialogType.Text, |
| colorKey: DialogType.ColorPicker, |
| avatarKey: DialogType.ImagePicker |
| }; |
| |
| class CroupierSettingsComponent extends StatefulComponent { |
| final NavigatorState navigator; |
| final logic_croupier.Croupier croupier; |
| final NoArgCb backCb; |
| |
| CroupierSettingsComponent(this.navigator, this.croupier, this.backCb); |
| |
| CroupierSettingsComponentState createState() => |
| new CroupierSettingsComponentState(); |
| } |
| |
| class CroupierSettingsComponentState extends State<CroupierSettingsComponent> { |
| Map<String, String> _tempData = new Map<String, String>(); |
| |
| void initState() { |
| super.initState(); |
| |
| _initializeTemp(); |
| } |
| |
| void _initializeTemp() { |
| _tempData[nameKey] = config.croupier.settings.name; |
| _tempData[colorKey] = "${config.croupier.settings.color}"; |
| _tempData[avatarKey] = config.croupier.settings.avatar; |
| } |
| |
| Widget _makeColoredRectangle(int colorInfo, String text, NoArgCb cb) { |
| return new Container( |
| decoration: new BoxDecoration(backgroundColor: new Color(colorInfo)), |
| child: new FlatButton( |
| child: new Text(""), enabled: cb != null, onPressed: cb)); |
| } |
| |
| Widget _makeImageButton(String url, NoArgCb cb) { |
| return new FlatButton( |
| child: new NetworkImage(src: url), enabled: cb != null, onPressed: cb); |
| } |
| |
| Widget build(BuildContext context) { |
| List<Widget> w = new List<Widget>(); |
| w.add(_makeButtonRow(nameKey, new Text(config.croupier.settings.name))); |
| w.add(_makeButtonRow(colorKey, |
| _makeColoredRectangle(config.croupier.settings.color, "", null))); |
| w.add(_makeButtonRow( |
| avatarKey, new NetworkImage(src: config.croupier.settings.avatar))); |
| |
| w.add(new FlatButton(child: new Text("Return"), onPressed: config.backCb)); |
| return new Column(w); |
| } |
| |
| Widget _makeButtonRow(String type, Widget child) { |
| String capType = _capitalize(type); |
| return new FlatButton( |
| onPressed: () => _handlePressed(type), |
| child: new Row([ |
| new Flexible( |
| flex: 1, |
| child: new Text(capType, style: Theme.of(context).text.subhead)), |
| new Flexible(flex: 3, child: child) |
| ], justifyContent: FlexJustifyContent.start)); |
| } |
| |
| void _handlePressed(String type) { |
| var capType = _capitalize(type); |
| showDialog(config.navigator, (NavigatorState navigator) { |
| switch (dialogTypes[type]) { |
| case DialogType.Text: |
| return new Dialog( |
| title: new Text(capType), |
| content: new Input( |
| key: globalKeys[type], |
| placeholder: capType, |
| initialValue: config.croupier.settings.getStringValue(type), |
| keyboardType: KeyboardType.TEXT, |
| onChanged: _makeHandleChanged(type)), onDismiss: () { |
| navigator.pop(); |
| }, actions: [ |
| new FlatButton(child: new Text('CANCEL'), onPressed: () { |
| navigator.pop(); |
| }), |
| new FlatButton(child: new Text('SAVE'), onPressed: () { |
| navigator.pop(_tempData[type]); |
| }), |
| ]); |
| case DialogType.ColorPicker: |
| List<Widget> flexColors = new List<Widget>(); |
| List<int> colors = <int>[ |
| 0xcfefefef, |
| 0xcfff3333, |
| 0xcf33ff33, |
| 0xcf3333ff, |
| 0xcf101010, |
| 0xcf33ffff, |
| 0xcfff33ff, |
| 0xcfffff33, |
| ]; |
| for (int i = 0; i < colors.length; i++) { |
| int c = colors[i]; |
| flexColors.add(_makeColoredRectangle(c, "", () { |
| // TODO(alexfandrianto): Remove this hack-y subtraction once the |
| // Dart + Android issue with int.parse is fixed. |
| navigator.pop("${c - 0xcf000000}"); |
| })); |
| } |
| |
| return new Dialog( |
| title: new Text(capType), |
| content: new Grid(flexColors, maxChildExtent: 75.0), |
| onDismiss: () { |
| navigator.pop(); |
| }, actions: [ |
| new FlatButton(child: new Text('CANCEL'), onPressed: () { |
| navigator.pop(); |
| }) |
| ]); |
| case DialogType.ImagePicker: |
| List<Widget> flexAvatars = new List<Widget>(); |
| for (int i = 0; i < RandomSettings.avatars.length; i++) { |
| String avatar = RandomSettings.avatars[i]; |
| flexAvatars.add(_makeImageButton(avatar, () { |
| navigator.pop(avatar); |
| })); |
| } |
| |
| return new Dialog( |
| title: new Text(capType), |
| content: new Grid(flexAvatars, maxChildExtent: 75.0), |
| onDismiss: () { |
| navigator.pop(); |
| }, actions: [ |
| new FlatButton(child: new Text('CANCEL'), onPressed: () { |
| navigator.pop(); |
| }) |
| ]); |
| default: |
| assert(false); |
| return null; |
| } |
| }).then((String data) => _persist(type, data)); |
| } |
| |
| void _persist(String type, String data) { |
| if (data == null) { |
| return; |
| } |
| setState(() { |
| config.croupier.settings.setStringValue(type, data); |
| config.croupier.settings_manager.save(config.croupier.settings.userID, |
| config.croupier.settings.toJSONString()); |
| }); |
| } |
| |
| String _capitalize(String s) => s[0].toUpperCase() + s.substring(1); |
| |
| OneStringCb _makeHandleChanged(String type) { |
| return (String data) { |
| setState(() { |
| print("Updating ${type} with ${data}"); |
| _tempData[type] = data; |
| }); |
| }; |
| } |
| } |