Resolves #273 New color picker
This commit is contained in:
parent
d8a1d03179
commit
0290cd3a32
@ -37,17 +37,19 @@ class LightEntity extends Entity {
|
||||
int get colorTemp => _getIntAttributeValue("color_temp");
|
||||
double get maxMireds => _getDoubleAttributeValue("max_mireds");
|
||||
double get minMireds => _getDoubleAttributeValue("min_mireds");
|
||||
Color get color => _getColor();
|
||||
HSVColor get color => _getColor();
|
||||
bool get isAdditionalControls => ((attributes["supported_features"] != null) && (attributes["supported_features"] != 0));
|
||||
List<String> get effectList => getStringListAttributeValue("effect_list");
|
||||
|
||||
LightEntity(Map rawData) : super(rawData);
|
||||
|
||||
Color _getColor() {
|
||||
List rgb = attributes["rgb_color"];
|
||||
HSVColor _getColor() {
|
||||
List hs = attributes["hs_color"];
|
||||
try {
|
||||
if ((rgb != null) && (rgb.length > 0)) {
|
||||
return Color.fromARGB(255, rgb[0], rgb[1], rgb[2]);
|
||||
if ((hs != null) && (hs.length > 0)) {
|
||||
double sat = hs[1]/100;
|
||||
String ssat = sat.toStringAsFixed(2);
|
||||
return HSVColor.fromAHSV(1.0, hs[0], double.parse(ssat), 1.0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
87
lib/entity_widgets/common/light_color_picker.dart
Normal file
87
lib/entity_widgets/common/light_color_picker.dart
Normal file
@ -0,0 +1,87 @@
|
||||
part of '../../main.dart';
|
||||
|
||||
class LightColorPicker extends StatefulWidget {
|
||||
|
||||
final HSVColor color;
|
||||
final onColorSelected;
|
||||
final double hueStep;
|
||||
final double saturationStep;
|
||||
final EdgeInsets padding;
|
||||
|
||||
LightColorPicker({this.color, this.onColorSelected, this.hueStep: 15.0, this.saturationStep: 0.2, this.padding: const EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, 0.0)});
|
||||
|
||||
@override
|
||||
LightColorPickerState createState() => new LightColorPickerState();
|
||||
}
|
||||
|
||||
class LightColorPickerState extends State<LightColorPicker> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> colors = [];
|
||||
Border border;
|
||||
Logger.d("Current colotfor picker: [${widget.color.hue}, ${widget.color.saturation}]");
|
||||
for (double saturation = 1.0; saturation >= (0.0 + widget.saturationStep); saturation = double.parse((saturation - widget.saturationStep).toStringAsFixed(2))) {
|
||||
List<Widget> rowChildren = [];
|
||||
Logger.d("$saturation");
|
||||
for (double hue = 0; hue <= (365 - widget.hueStep);
|
||||
hue += widget.hueStep) {
|
||||
if (widget.color.hue.round() >= hue && widget.color.hue.round() < (hue+widget.hueStep) && widget.color.saturation == saturation) {
|
||||
border = Border.all(
|
||||
width: 2.0,
|
||||
color: Colors.white,
|
||||
);
|
||||
} else {
|
||||
border = null;
|
||||
}
|
||||
HSVColor currentColor = HSVColor.fromAHSV(1.0, hue, double.parse(saturation.toStringAsFixed(2)), 1.0);
|
||||
rowChildren.add(
|
||||
Flexible(
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
height: 40.0,
|
||||
decoration: BoxDecoration(
|
||||
color: currentColor.toColor(),
|
||||
border: border,
|
||||
),
|
||||
),
|
||||
onTap: () => widget.onColorSelected(currentColor),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
colors.add(
|
||||
Row(
|
||||
children: rowChildren,
|
||||
)
|
||||
);
|
||||
}
|
||||
colors.add(
|
||||
Flexible(
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
height: 40.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white
|
||||
),
|
||||
),
|
||||
onTap: () => widget.onColorSelected(HSVColor.fromAHSV(1.0, 30.0, 0.0, 1.0)),
|
||||
)
|
||||
)
|
||||
);
|
||||
return Padding(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: colors,
|
||||
),
|
||||
padding: widget.padding,
|
||||
);
|
||||
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@ class ModeSelectorWidget extends StatelessWidget {
|
||||
final String value;
|
||||
final double captionFontSize;
|
||||
final double valueFontSize;
|
||||
final double bottomPadding;
|
||||
final onChange;
|
||||
final EdgeInsets padding;
|
||||
|
||||
ModeSelectorWidget({
|
||||
Key key,
|
||||
@ -18,12 +18,14 @@ class ModeSelectorWidget extends StatelessWidget {
|
||||
@required this.onChange,
|
||||
this.captionFontSize,
|
||||
this.valueFontSize,
|
||||
this.bottomPadding
|
||||
this.padding: const EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, 0.0),
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
return Padding(
|
||||
padding: padding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text("$caption", style: TextStyle(
|
||||
@ -54,9 +56,9 @@ class ModeSelectorWidget extends StatelessWidget {
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Container(height: bottomPadding ?? Sizes.rowPadding,)
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -10,8 +10,9 @@ class UniversalSlider extends StatelessWidget {
|
||||
final double min;
|
||||
final double max;
|
||||
final double value;
|
||||
final EdgeInsets padding;
|
||||
|
||||
const UniversalSlider({Key key, this.onChanged, this.onChangeEnd, this.leading, this.closing, this.title, this.min, this.max, this.value}) : super(key: key);
|
||||
const UniversalSlider({Key key, this.onChanged, this.onChangeEnd, this.leading, this.closing, this.title, this.min, this.max, this.value, this.padding: const EdgeInsets.fromLTRB(Sizes.leftWidgetPadding, Sizes.rowPadding, Sizes.rightWidgetPadding, 0.0)}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -33,7 +34,9 @@ class UniversalSlider extends StatelessWidget {
|
||||
if (closing != null) {
|
||||
row.add(closing);
|
||||
}
|
||||
return Column(
|
||||
return Padding(
|
||||
padding: padding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(height: Sizes.rowPadding,),
|
||||
@ -48,6 +51,7 @@ class UniversalSlider extends StatelessWidget {
|
||||
),
|
||||
Container(height: Sizes.rowPadding,)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ class _LightControlsWidgetState extends State<LightControlsWidget> {
|
||||
|
||||
int _tmpBrightness;
|
||||
int _tmpColorTemp = 0;
|
||||
Color _tmpColor = Colors.white;
|
||||
HSVColor _tmpColor = HSVColor.fromAHSV(1.0, 30.0, 0.0, 1.0);
|
||||
bool _changedHere = false;
|
||||
String _tmpEffect;
|
||||
|
||||
@ -48,20 +48,14 @@ class _LightControlsWidgetState extends State<LightControlsWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
void _setColor(LightEntity entity, Color color) {
|
||||
void _setColor(LightEntity entity, HSVColor color) {
|
||||
setState(() {
|
||||
_tmpColor = color;
|
||||
_changedHere = true;
|
||||
Logger.d( "Color: [${color.red}, ${color.green}, ${color.blue}]");
|
||||
if ((color == Colors.black) || ((color.red == color.green) && (color.green == color.blue))) {
|
||||
eventBus.fire(new ServiceCallEvent(
|
||||
entity.domain, "turn_off", entity.entityId,
|
||||
null));
|
||||
} else {
|
||||
Logger.d( "HS Color: [${color.hue}, ${color.saturation}]");
|
||||
eventBus.fire(new ServiceCallEvent(
|
||||
entity.domain, "turn_on", entity.entityId,
|
||||
{"rgb_color": [color.red, color.green, color.blue]}));
|
||||
}
|
||||
{"hs_color": [color.hue, color.saturation*100]}));
|
||||
});
|
||||
}
|
||||
|
||||
@ -142,25 +136,9 @@ class _LightControlsWidgetState extends State<LightControlsWidget> {
|
||||
|
||||
Widget _buildColorControl(LightEntity entity) {
|
||||
if (entity.supportColor) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(height: Sizes.rowPadding,),
|
||||
RaisedButton(
|
||||
onPressed: () => _showColorPicker(entity),
|
||||
color: _tmpColor ?? Colors.black45,
|
||||
child: Text(
|
||||
"COLOR",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 50.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(height: 2*Sizes.rowPadding,),
|
||||
],
|
||||
return LightColorPicker(
|
||||
color: _tmpColor,
|
||||
onColorSelected: (color) => _setColor(entity, color),
|
||||
);
|
||||
} else {
|
||||
return Container(width: 0.0, height: 0.0);
|
||||
@ -174,15 +152,8 @@ class _LightControlsWidgetState extends State<LightControlsWidget> {
|
||||
return AlertDialog(
|
||||
titlePadding: EdgeInsets.all(0.0),
|
||||
contentPadding: EdgeInsets.all(0.0),
|
||||
content: SingleChildScrollView(
|
||||
child: MaterialPicker(
|
||||
pickerColor: _tmpColor,
|
||||
onColorChanged: (color) {
|
||||
_setColor(entity, color);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
enableLabel: true,
|
||||
),
|
||||
content: LightColorPicker(
|
||||
color: _tmpColor,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -12,7 +12,6 @@ import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:date_format/date_format.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter_colorpicker/material_picker.dart';
|
||||
import 'package:charts_flutter/flutter.dart' as charts;
|
||||
import 'package:progress_indicators/progress_indicators.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
@ -50,6 +49,7 @@ part 'entity_widgets/common/mode_swicth.dart';
|
||||
part 'entity_widgets/common/mode_selector.dart';
|
||||
part 'entity_widgets/common/universal_slider.dart';
|
||||
part 'entity_widgets/common/flat_service_button.dart';
|
||||
part 'entity_widgets/common/light_color_picker.dart';
|
||||
part 'entity_widgets/entity_colors.class.dart';
|
||||
part 'entity_widgets/entity_page_container.dart';
|
||||
part 'entity_widgets/history_chart/entity_history.dart';
|
||||
|
15
pubspec.lock
15
pubspec.lock
@ -112,14 +112,7 @@ packages:
|
||||
name: flutter_cache_manager
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.0-alpha.2"
|
||||
flutter_colorpicker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_colorpicker
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.1"
|
||||
version: "0.3.0-beta.2+1"
|
||||
flutter_launcher_icons:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -159,7 +152,7 @@ packages:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
version: "2.0.7"
|
||||
intl:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -236,7 +229,7 @@ packages:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "0.5.1+1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -311,7 +304,7 @@ packages:
|
||||
name: url_launcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
version: "5.0.1"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -16,7 +16,6 @@ dependencies:
|
||||
cached_network_image: any
|
||||
url_launcher: any
|
||||
date_format: any
|
||||
flutter_colorpicker: any
|
||||
charts_flutter: any
|
||||
flutter_markdown: any
|
||||
|
||||
|
Reference in New Issue
Block a user