This commit is contained in:
Yegor Vialov 2018-11-17 22:40:33 +02:00
parent 1e4cb03470
commit 96f1211395
10 changed files with 355 additions and 191 deletions

View File

@ -72,4 +72,9 @@ class MediaPlayerEntity extends Entity {
MediaPlayerEntity.SUPPORT_SELECT_SOUND_MODE) == MediaPlayerEntity.SUPPORT_SELECT_SOUND_MODE) ==
MediaPlayerEntity.SUPPORT_SELECT_SOUND_MODE); MediaPlayerEntity.SUPPORT_SELECT_SOUND_MODE);
@override
Widget _buildAdditionalControlsForPage(BuildContext context) {
return MediaPlayerControls();
}
} }

View File

@ -1,4 +1,4 @@
part of '../main.dart'; part of '../../main.dart';
class BadgeWidget extends StatelessWidget { class BadgeWidget extends StatelessWidget {
@override @override

View File

@ -1,4 +1,4 @@
part of '../main.dart'; part of '../../main.dart';
class EntityAttributesList extends StatelessWidget { class EntityAttributesList extends StatelessWidget {
EntityAttributesList({Key key}) : super(key: key); EntityAttributesList({Key key}) : super(key: key);

View File

@ -1,4 +1,4 @@
part of '../main.dart'; part of '../../main.dart';
class LastUpdatedWidget extends StatelessWidget { class LastUpdatedWidget extends StatelessWidget {
@override @override

View File

@ -1,4 +1,4 @@
part of '../main.dart'; part of '../../main.dart';
class ModeSelectorWidget extends StatelessWidget { class ModeSelectorWidget extends StatelessWidget {

View File

@ -1,4 +1,4 @@
part of '../main.dart'; part of '../../main.dart';
class ModeSwitchWidget extends StatelessWidget { class ModeSwitchWidget extends StatelessWidget {

View File

@ -0,0 +1,54 @@
part of '../../main.dart';
class UniversalSlider extends StatelessWidget {
final onChanged;
final onChangeEnd;
final Widget leading;
final Widget closing;
final String title;
final double min;
final double max;
final double value;
const UniversalSlider({Key key, this.onChanged, this.onChangeEnd, this.leading, this.closing, this.title, this.min, this.max, this.value}) : super(key: key);
@override
Widget build(BuildContext context) {
List <Widget> row = [];
if (leading != null) {
row.add(leading);
}
row.add(
Flexible(
child: Slider(
value: value,
min: min,
max: max,
onChanged: (value) => onChanged(value),
onChangeEnd: (value) => onChangeEnd(value),
),
)
);
if (closing != null) {
row.add(closing);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(height: Sizes.rowPadding,),
Text(
"$title",
style: TextStyle(fontSize: Sizes.stateFontSize),
),
Container(height: Sizes.rowPadding,),
Row(
mainAxisSize: MainAxisSize.min,
children: row,
),
Container(height: Sizes.rowPadding,)
],
);
}
}

View File

@ -99,36 +99,19 @@ class _LightControlsWidgetState extends State<LightControlsWidget> {
Widget _buildBrightnessControl(LightEntity entity) { Widget _buildBrightnessControl(LightEntity entity) {
if ((entity.supportBrightness) && (_tmpBrightness != null) && (entity.state != EntityState.unavailable)) { if ((entity.supportBrightness) && (_tmpBrightness != null) && (entity.state != EntityState.unavailable)) {
return Column( return UniversalSlider(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(height: Sizes.rowPadding,),
Text(
"Brightness",
style: TextStyle(fontSize: Sizes.stateFontSize),
),
Container(height: Sizes.rowPadding,),
Row(
children: <Widget>[
Icon(Icons.brightness_5),
Expanded(
child: Slider(
value: _tmpBrightness.toDouble(),
min: 0.0,
max: 255.0,
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
_changedHere = true; _changedHere = true;
_tmpBrightness = value.round(); _tmpBrightness = value.round();
}); });
}, },
min: 0.0,
max: 255.0,
onChangeEnd: (value) => _setBrightness(entity, value), onChangeEnd: (value) => _setBrightness(entity, value),
), value: _tmpBrightness.toDouble(),
) leading: Icon(Icons.brightness_5),
], title: "Brightness",
),
Container(height: Sizes.rowPadding,)
],
); );
} else { } else {
return Container(width: 0.0, height: 0.0); return Container(width: 0.0, height: 0.0);
@ -137,37 +120,20 @@ class _LightControlsWidgetState extends State<LightControlsWidget> {
Widget _buildColorTempControl(LightEntity entity) { Widget _buildColorTempControl(LightEntity entity) {
if ((entity.supportColorTemp) && (_tmpColorTemp != null)) { if ((entity.supportColorTemp) && (_tmpColorTemp != null)) {
return Column( return UniversalSlider(
crossAxisAlignment: CrossAxisAlignment.start, title: "Color temperature",
children: <Widget>[ leading: Text("Cold", style: TextStyle(color: Colors.lightBlue),),
Container(height: Sizes.rowPadding,),
Text(
"Color temperature",
style: TextStyle(fontSize: Sizes.stateFontSize),
),
Container(height: Sizes.rowPadding,),
Row(
children: <Widget>[
Text("Cold", style: TextStyle(color: Colors.lightBlue),),
Expanded(
child: Slider(
value: _tmpColorTemp.toDouble(), value: _tmpColorTemp.toDouble(),
min: entity.minMireds, onChangeEnd: (value) => _setColorTemp(entity, value),
max: entity.maxMireds, max: entity.maxMireds,
min: entity.minMireds,
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
_changedHere = true; _changedHere = true;
_tmpColorTemp = value.round(); _tmpColorTemp = value.round();
}); });
}, },
onChangeEnd: (value) => _setColorTemp(entity, value), closing: Text("Warm", style: TextStyle(color: Colors.amberAccent),),
),
),
Text("Warm", style: TextStyle(color: Colors.amberAccent),),
],
),
Container(height: Sizes.rowPadding,)
],
); );
} else { } else {
return Container(width: 0.0, height: 0.0); return Container(width: 0.0, height: 0.0);

View File

@ -2,33 +2,11 @@ part of '../../main.dart';
class MediaPlayerWidget extends StatelessWidget { class MediaPlayerWidget extends StatelessWidget {
void _setPower(MediaPlayerEntity entity) {
if (entity.state != EntityState.unavailable && entity.state != EntityState.unknown) {
if (entity.state == EntityState.off) {
TheLogger.debug("${entity.entityId} turn_on");
eventBus.fire(new ServiceCallEvent(
entity.domain, "turn_on", entity.entityId,
null));
} else {
TheLogger.debug("${entity.entityId} turn_off");
eventBus.fire(new ServiceCallEvent(
entity.domain, "turn_off", entity.entityId,
null));
}
}
}
void _callAction(MediaPlayerEntity entity, String action) {
TheLogger.debug("${entity.entityId} $action");
eventBus.fire(new ServiceCallEvent(
entity.domain, "$action", entity.entityId,
null));
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final EntityModel entityModel = EntityModel.of(context); final EntityModel entityModel = EntityModel.of(context);
final MediaPlayerEntity entity = entityModel.entityWrapper.entity; final MediaPlayerEntity entity = entityModel.entityWrapper.entity;
//TheLogger.debug("stop: ${entity.supportStop}, seek: ${entity.supportSeek}");
return Column( return Column(
children: <Widget>[ children: <Widget>[
Stack( Stack(
@ -52,105 +30,11 @@ class MediaPlayerWidget extends StatelessWidget {
) )
], ],
), ),
_buildControls(entity) MediaPlayerPlaybackControls()
] ]
); );
} }
Widget _buildControls(MediaPlayerEntity entity) {
List<Widget> result = [];
if (entity.supportTurnOn || entity.supportTurnOff) {
result.add(
IconButton(
icon: Icon(Icons.power_settings_new),
onPressed: () => _setPower(entity),
iconSize: Sizes.iconSize,
)
);
} else {
result.add(
Container(
width: Sizes.iconSize,
)
);
}
List <Widget> centeredControlsChildren = [];
if (entity.supportPreviousTrack) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.skip_previous),
onPressed: () => _callAction(entity, "media_previous_track"),
iconSize: Sizes.iconSize,
)
);
}
if (entity.supportPlay || entity.supportPause) {
if (entity.state == EntityState.playing) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.pause_circle_filled),
color: Colors.blue,
onPressed: () => _callAction(entity, "media_pause"),
iconSize: Sizes.iconSize*1.8,
)
);
} else if (entity.state == EntityState.paused) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.play_circle_filled),
color: Colors.blue,
onPressed: () => _callAction(entity, "media_play"),
iconSize: Sizes.iconSize*1.8,
)
);
} else {
centeredControlsChildren.add(
Container(
width: Sizes.iconSize*1.8,
height: Sizes.iconSize*2.0,
)
);
}
}
if (entity.supportNextTrack) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.skip_next),
onPressed: () => _callAction(entity, "media_next_track"),
iconSize: Sizes.iconSize,
)
);
}
if (centeredControlsChildren.isNotEmpty) {
result.add(
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: centeredControlsChildren,
)
)
);
} else {
result.add(
Expanded(
child: Container(
height: 10.0,
),
)
);
}
result.add(
IconButton(
icon: Icon(MaterialDesignIcons.createIconDataFromIconName("mdi:dots-vertical")),
onPressed: () => eventBus.fire(new ShowEntityPageEvent(entity))
)
);
return Row(
children: result,
mainAxisAlignment: MainAxisAlignment.center,
);
}
Widget _buildState(MediaPlayerEntity entity) { Widget _buildState(MediaPlayerEntity entity) {
TextStyle style = TextStyle( TextStyle style = TextStyle(
fontSize: 14.0, fontSize: 14.0,
@ -165,7 +49,13 @@ class MediaPlayerWidget extends StatelessWidget {
states.add(Text("${entity.state}", style: style.apply(fontSizeDelta: 4.0),)); states.add(Text("${entity.state}", style: style.apply(fontSizeDelta: 4.0),));
} }
if (entity.attributes['media_title'] != null) { if (entity.attributes['media_title'] != null) {
states.add(Text("${entity.attributes['media_title']}", style: style.apply(fontSizeDelta: 6.0, fontWeightDelta: 50),)); states.add(Text(
"${entity.attributes['media_title']}",
style: style.apply(fontSizeDelta: 6.0, fontWeightDelta: 50),
maxLines: 1,
softWrap: true,
overflow: TextOverflow.ellipsis,
));
} }
if (entity.attributes['media_content_type'] == "music") { if (entity.attributes['media_content_type'] == "music") {
states.add(Text("${entity.attributes['media_artist'] ?? entity.attributes['app_name']}", style: style.apply(fontSizeDelta: 4.0),)); states.add(Text("${entity.attributes['media_artist'] ?? entity.attributes['app_name']}", style: style.apply(fontSizeDelta: 4.0),));
@ -217,6 +107,254 @@ class MediaPlayerWidget extends StatelessWidget {
} }
} }
class MediaPlayerPlaybackControls extends StatelessWidget {
final bool showMenu;
final bool showStop;
const MediaPlayerPlaybackControls({Key key, this.showMenu: true, this.showStop: false}) : super(key: key);
void _setPower(MediaPlayerEntity entity) {
if (entity.state != EntityState.unavailable && entity.state != EntityState.unknown) {
if (entity.state == EntityState.off) {
TheLogger.debug("${entity.entityId} turn_on");
eventBus.fire(new ServiceCallEvent(
entity.domain, "turn_on", entity.entityId,
null));
} else {
TheLogger.debug("${entity.entityId} turn_off");
eventBus.fire(new ServiceCallEvent(
entity.domain, "turn_off", entity.entityId,
null));
}
}
}
void _callAction(MediaPlayerEntity entity, String action) {
TheLogger.debug("${entity.entityId} $action");
eventBus.fire(new ServiceCallEvent(
entity.domain, "$action", entity.entityId,
null));
}
@override
Widget build(BuildContext context) {
final MediaPlayerEntity entity = EntityModel.of(context).entityWrapper.entity;
List<Widget> result = [];
if (entity.supportTurnOn || entity.supportTurnOff) {
result.add(
IconButton(
icon: Icon(Icons.power_settings_new),
onPressed: () => _setPower(entity),
iconSize: Sizes.iconSize,
)
);
} else {
result.add(
Container(
width: Sizes.iconSize,
)
);
}
List <Widget> centeredControlsChildren = [];
if (entity.supportPreviousTrack && entity.state != EntityState.off && entity.state != EntityState.unavailable) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.skip_previous),
onPressed: () => _callAction(entity, "media_previous_track"),
iconSize: Sizes.iconSize,
)
);
}
if (entity.supportPlay || entity.supportPause) {
if (entity.state == EntityState.playing) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.pause_circle_filled),
color: Colors.blue,
onPressed: () => _callAction(entity, "media_pause"),
iconSize: Sizes.iconSize*1.8,
)
);
} else if (entity.state == EntityState.paused || entity.state == EntityState.idle) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.play_circle_filled),
color: Colors.blue,
onPressed: () => _callAction(entity, "media_play"),
iconSize: Sizes.iconSize*1.8,
)
);
} else {
centeredControlsChildren.add(
Container(
width: Sizes.iconSize*1.8,
height: Sizes.iconSize*2.0,
)
);
}
}
if (entity.supportNextTrack && entity.state != EntityState.off && entity.state != EntityState.unavailable) {
centeredControlsChildren.add(
IconButton(
icon: Icon(Icons.skip_next),
onPressed: () => _callAction(entity, "media_next_track"),
iconSize: Sizes.iconSize,
)
);
}
if (centeredControlsChildren.isNotEmpty) {
result.add(
Expanded(
child: Row(
mainAxisAlignment: showMenu ? MainAxisAlignment.center : MainAxisAlignment.end,
children: centeredControlsChildren,
)
)
);
} else {
result.add(
Expanded(
child: Container(
height: 10.0,
),
)
);
}
if (showMenu) {
result.add(
IconButton(
icon: Icon(MaterialDesignIcons.createIconDataFromIconName(
"mdi:dots-vertical")),
onPressed: () => eventBus.fire(new ShowEntityPageEvent(entity))
)
);
} else if (entity.supportStop && entity.state != EntityState.off && entity.state != EntityState.unavailable) {
result.add(
IconButton(
icon: Icon(Icons.stop),
onPressed: () => _callAction(entity, "media_stop")
)
);
}
return Row(
children: result,
mainAxisAlignment: MainAxisAlignment.center,
);
}
}
class MediaPlayerControls extends StatefulWidget {
@override
_MediaPlayerControlsState createState() => _MediaPlayerControlsState();
}
class _MediaPlayerControlsState extends State<MediaPlayerControls> {
double _newVolumeLevel;
bool _changedHere = false;
void _setVolume(double value, String entityId) {
setState(() {
_changedHere = true;
_newVolumeLevel = value;
eventBus.fire(ServiceCallEvent("media_player", "volume_set", entityId, {"volume_level": value}));
});
}
void _setVolumeMute(bool isMuted, String entityId) {
eventBus.fire(ServiceCallEvent("media_player", "volume_mute", entityId, {"is_volume_muted": isMuted}));
}
void _setVolumeUp(String entityId) {
eventBus.fire(ServiceCallEvent("media_player", "volume_up", entityId, null));
}
void _setVolumeDown(String entityId) {
eventBus.fire(ServiceCallEvent("media_player", "volume_down", entityId, null));
}
@override
Widget build(BuildContext context) {
final MediaPlayerEntity entity = EntityModel.of(context).entityWrapper.entity;
List<Widget> children = [
MediaPlayerPlaybackControls(
showMenu: false,
)
];
if (entity.state != EntityState.off && entity.state != EntityState.unknown && entity.state != EntityState.unavailable) {
Widget muteWidget;
Widget volumeStepWidget;
if (entity.supportVolumeMute) {
bool isMuted = entity.attributes["is_volume_muted"] ?? false;
muteWidget =
IconButton(
icon: Icon(isMuted ? Icons.volume_off : Icons.volume_up),
onPressed: () => _setVolumeMute(!isMuted, entity.entityId)
);
} else {
muteWidget = Container(width: 0.0, height: 0.0,);
}
if (entity.supportVolumeStep) {
volumeStepWidget = Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(MaterialDesignIcons.createIconDataFromIconName("mdi:plus")),
onPressed: () => _setVolumeUp(entity.entityId)
),
IconButton(
icon: Icon(MaterialDesignIcons.createIconDataFromIconName("mdi:minus")),
onPressed: () => _setVolumeDown(entity.entityId)
)
],
);
} else {
volumeStepWidget = Container(width: 0.0, height: 0.0,);
}
if (entity.supportVolumeSet) {
if (!_changedHere) {
_newVolumeLevel = entity._getDoubleAttributeValue("volume_level");
} else {
_changedHere = false;
}
children.add(
UniversalSlider(
leading: muteWidget,
closing: volumeStepWidget,
title: "Volume",
onChanged: (value) {
setState(() {
_changedHere = true;
_newVolumeLevel = value;
});
},
value: _newVolumeLevel,
onChangeEnd: (value) => _setVolume(value, entity.entityId),
max: 1.0,
min: 0.0,
)
);
} else {
children.add(Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
muteWidget,
volumeStepWidget
],
));
}
}
return Column(
children: children,
);
}
}
class MediaPlayerProgressWidget extends StatefulWidget { class MediaPlayerProgressWidget extends StatefulWidget {
@override @override
_MediaPlayerProgressWidgetState createState() => _MediaPlayerProgressWidgetState(); _MediaPlayerProgressWidgetState createState() => _MediaPlayerProgressWidgetState();

View File

@ -29,16 +29,17 @@ part 'entity_class/select_entity.class.dart';
part 'entity_class/other_entity.class.dart'; part 'entity_class/other_entity.class.dart';
part 'entity_class/slider_entity.dart'; part 'entity_class/slider_entity.dart';
part 'entity_class/media_player_entity.class.dart'; part 'entity_class/media_player_entity.class.dart';
part 'entity_widgets/badge.dart'; part 'entity_widgets/common/badge.dart';
part 'entity_widgets/model_widgets.dart'; part 'entity_widgets/model_widgets.dart';
part 'entity_widgets/default_entity_container.dart'; part 'entity_widgets/default_entity_container.dart';
part 'entity_widgets/glance_entity_container.dart'; part 'entity_widgets/glance_entity_container.dart';
part 'entity_widgets/entity_attributes_list.dart'; part 'entity_widgets/common/entity_attributes_list.dart';
part 'entity_widgets/entity_icon.dart'; part 'entity_widgets/entity_icon.dart';
part 'entity_widgets/entity_name.dart'; part 'entity_widgets/entity_name.dart';
part 'entity_widgets/last_updated.dart'; part 'entity_widgets/common/last_updated.dart';
part 'entity_widgets/mode_swicth.dart'; part 'entity_widgets/common/mode_swicth.dart';
part 'entity_widgets/mode_selector.dart'; part 'entity_widgets/common/mode_selector.dart';
part 'entity_widgets/common/universal_slider.dart';
part 'entity_widgets/entity_colors.class.dart'; part 'entity_widgets/entity_colors.class.dart';
part 'entity_widgets/entity_page_container.dart'; part 'entity_widgets/entity_page_container.dart';
part 'entity_widgets/history_chart/entity_history.dart'; part 'entity_widgets/history_chart/entity_history.dart';
@ -59,7 +60,7 @@ part 'entity_widgets/state/button_state.dart';
part 'entity_widgets/controls/climate_controls.dart'; part 'entity_widgets/controls/climate_controls.dart';
part 'entity_widgets/controls/cover_controls.dart'; part 'entity_widgets/controls/cover_controls.dart';
part 'entity_widgets/controls/light_controls.dart'; part 'entity_widgets/controls/light_controls.dart';
part 'entity_widgets/controls/media_player_widget.dart'; part 'entity_widgets/controls/media_player_widgets.dart';
part 'settings.page.dart'; part 'settings.page.dart';
part 'home_assistant.class.dart'; part 'home_assistant.class.dart';
part 'log.page.dart'; part 'log.page.dart';