diff --git a/lib/entity_class/entity.class.dart b/lib/entity_class/entity.class.dart index dc78763..508df0e 100644 --- a/lib/entity_class/entity.class.dart +++ b/lib/entity_class/entity.class.dart @@ -88,6 +88,14 @@ class Entity { ); } + Widget buildGlanceWidget(BuildContext context) { + return EntityModel( + entity: this, + child: GlanceEntityContainer(), + handleTap: true, + ); + } + Widget _buildStatePart(BuildContext context) { return SimpleEntityState(); } diff --git a/lib/entity_widgets/entity_icon.dart b/lib/entity_widgets/entity_icon.dart index 991ef70..4ea4395 100644 --- a/lib/entity_widgets/entity_icon.dart +++ b/lib/entity_widgets/entity_icon.dart @@ -1,16 +1,22 @@ part of '../main.dart'; class EntityIcon extends StatelessWidget { + + final EdgeInsetsGeometry padding; + final double iconSize; + + const EntityIcon({Key key, this.iconSize: Sizes.iconSize, this.padding: const EdgeInsets.fromLTRB( + Sizes.leftWidgetPadding, 0.0, 12.0, 0.0)}) : super(key: key); + @override Widget build(BuildContext context) { final entityModel = EntityModel.of(context); return GestureDetector( child: Padding( - padding: EdgeInsets.fromLTRB( - Sizes.leftWidgetPadding, 0.0, 12.0, 0.0), + padding: padding, child: MaterialDesignIcons.createIconWidgetFromEntityData( entityModel.entity, - Sizes.iconSize, + iconSize, EntityColor.stateColor(entityModel.entity.state) ), ), diff --git a/lib/entity_widgets/entity_name.dart b/lib/entity_widgets/entity_name.dart index 3d74565..cd92c50 100644 --- a/lib/entity_widgets/entity_name.dart +++ b/lib/entity_widgets/entity_name.dart @@ -1,16 +1,21 @@ part of '../main.dart'; class EntityName extends StatelessWidget { + + final EdgeInsetsGeometry padding; + + const EntityName({Key key, this.padding: const EdgeInsets.only(right: 10.0)}) : super(key: key); + @override Widget build(BuildContext context) { final entityModel = EntityModel.of(context); return GestureDetector( child: Padding( - padding: EdgeInsets.only(right: 10.0), + padding: padding, child: Text( "${entityModel.entity.displayName}", overflow: TextOverflow.ellipsis, - softWrap: false, + softWrap: true, style: TextStyle(fontSize: Sizes.nameFontSize), ), ), diff --git a/lib/entity_widgets/glance_entity_container.dart b/lib/entity_widgets/glance_entity_container.dart new file mode 100644 index 0000000..435ccfb --- /dev/null +++ b/lib/entity_widgets/glance_entity_container.dart @@ -0,0 +1,30 @@ +part of '../main.dart'; + +class GlanceEntityContainer extends StatelessWidget { + GlanceEntityContainer({ + Key key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + EntityName( + padding: EdgeInsets.all(0.0), + ), + EntityIcon( + padding: EdgeInsets.all(0.0), + iconSize: Sizes.largeIconSize, + ), + SimpleEntityState( + textAlign: TextAlign.center, + expanded: false, + padding: EdgeInsets.all(0.0), + ) + ], + ); + } +} \ No newline at end of file diff --git a/lib/entity_widgets/state/simple_state.dart b/lib/entity_widgets/state/simple_state.dart index 2e17a59..a56e00c 100644 --- a/lib/entity_widgets/state/simple_state.dart +++ b/lib/entity_widgets/state/simple_state.dart @@ -3,18 +3,20 @@ part of '../../main.dart'; class SimpleEntityState extends StatelessWidget { final bool expanded; + final TextAlign textAlign; + final EdgeInsetsGeometry padding; - const SimpleEntityState({Key key, this.expanded: true}) : super(key: key); + const SimpleEntityState({Key key, this.expanded: true, this.textAlign: TextAlign.right, this.padding: const EdgeInsets.fromLTRB(0.0, 0.0, Sizes.rightWidgetPadding, 0.0)}) : super(key: key); @override Widget build(BuildContext context) { final entityModel = EntityModel.of(context); Widget result = Padding( - padding: EdgeInsets.fromLTRB(0.0, 0.0, Sizes.rightWidgetPadding, 0.0), + padding: padding, child: GestureDetector( child: Text( "${entityModel.entity.state}${entityModel.entity.unitOfMeasurement}", - textAlign: TextAlign.right, + textAlign: textAlign, maxLines: 4, overflow: TextOverflow.ellipsis, softWrap: true, diff --git a/lib/home_assistant.class.dart b/lib/home_assistant.class.dart index 94ad8e3..5eb0ac4 100644 --- a/lib/home_assistant.class.dart +++ b/lib/home_assistant.class.dart @@ -411,7 +411,8 @@ class HomeAssistant { HACard card = HACard( id: "card", name: rawCard["title"], - type: rawCard['type'] + type: rawCard['type'], + columnsCount: rawCard['columns'] ?? 4, ); rawCard["entities"]?.forEach((rawEntity) { if (rawEntity is String) { diff --git a/lib/main.dart b/lib/main.dart index 280275d..3df1a5b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -31,6 +31,7 @@ part 'entity_class/media_player_entity.class.dart'; part 'entity_widgets/badge.dart'; part 'entity_widgets/model_widgets.dart'; part 'entity_widgets/default_entity_container.dart'; +part 'entity_widgets/glance_entity_container.dart'; part 'entity_widgets/entity_attributes_list.dart'; part 'entity_widgets/entity_icon.dart'; part 'entity_widgets/entity_name.dart'; @@ -71,6 +72,7 @@ part 'ui_class/card.class.dart'; part 'ui_class/sizes_class.dart'; part 'ui_widgets/view.dart'; part 'ui_widgets/entities_card.dart'; +part 'ui_widgets/glance_card.dart'; part 'ui_widgets/unsupported_card.dart'; part 'ui_widgets/media_control_card.dart'; part 'ui_widgets/card_header_widget.dart'; diff --git a/lib/ui_class/card.class.dart b/lib/ui_class/card.class.dart index 75f24a7..314c3fe 100644 --- a/lib/ui_class/card.class.dart +++ b/lib/ui_class/card.class.dart @@ -6,11 +6,13 @@ class HACard { String name; String id; String type; + int columnsCount; HACard({ this.name, this.id, this.linkedEntity, + this.columnsCount: 4, @required this.type }); @@ -23,6 +25,12 @@ class HACard { ); } + case "glance": { + return GlanceCardWidget( + card: this, + ); + } + case "media-control": { return MediaControlCardWidget( card: this, diff --git a/lib/ui_class/sizes_class.dart b/lib/ui_class/sizes_class.dart index b0f04a8..096b77f 100644 --- a/lib/ui_class/sizes_class.dart +++ b/lib/ui_class/sizes_class.dart @@ -5,6 +5,7 @@ class Sizes { static const leftWidgetPadding = 8.0; static const extendedWidgetHeight = 50.0; static const iconSize = 28.0; + static const largeIconSize = 34.0; static const stateFontSize = 16.0; static const nameFontSize = 16.0; static const smallFontSize = 14.0; diff --git a/lib/ui_widgets/entities_card.dart b/lib/ui_widgets/entities_card.dart index af00381..7439892 100644 --- a/lib/ui_widgets/entities_card.dart +++ b/lib/ui_widgets/entities_card.dart @@ -28,7 +28,7 @@ class EntitiesCardWidget extends StatelessWidget { if (!entity.isHidden) { result.add( Padding( - padding: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), + padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, Sizes.rowPadding), child: entity.buildDefaultWidget(context), )); } diff --git a/lib/ui_widgets/glance_card.dart b/lib/ui_widgets/glance_card.dart new file mode 100644 index 0000000..c202b6b --- /dev/null +++ b/lib/ui_widgets/glance_card.dart @@ -0,0 +1,50 @@ +part of '../main.dart'; + +class GlanceCardWidget extends StatelessWidget { + + final HACard card; + + const GlanceCardWidget({ + Key key, + this.card + }) : super(key: key); + + @override + Widget build(BuildContext context) { + if ((card.linkedEntity!= null) && (card.linkedEntity.isHidden)) { + return Container(width: 0.0, height: 0.0,); + } + List rows = []; + rows.add(CardHeaderWidget(name: card.name)); + rows.add(_buildRows(context)); + return Card( + child: new Column(mainAxisSize: MainAxisSize.min, children: rows) + ); + } + + Widget _buildRows(BuildContext context) { + List result = []; + double width = MediaQuery.of(context).size.width - Sizes.leftWidgetPadding - (2*Sizes.rightWidgetPadding); + List toShow = card.entities.where((entity) {return !entity.isHidden;}).toList(); + int columnsCount = toShow.length >= card.columnsCount ? card.columnsCount : toShow.length; + card.entities.forEach((Entity entity) { + if (!entity.isHidden) { + result.add( + SizedBox( + width: width / columnsCount, + child: entity.buildGlanceWidget(context), + ) + ); + } + }); + return Padding( + padding: EdgeInsets.fromLTRB(0.0, Sizes.rowPadding, 0.0, 2*Sizes.rowPadding), + child: Wrap( + alignment: WrapAlignment.spaceAround, + runSpacing: Sizes.rowPadding*2, + children: result, + ), + ); + } + +} \ No newline at end of file