[Ermine] Added filled progress bar visualization
Change-Id: Ibf92880bec2accd0541b44fa86347e677f23d002
diff --git a/shell/ermine/BUILD.gn b/shell/ermine/BUILD.gn
index ec7d8f3..117bcba 100644
--- a/shell/ermine/BUILD.gn
+++ b/shell/ermine/BUILD.gn
@@ -61,7 +61,8 @@
"src/widgets/tile_chrome.dart",
"src/widgets/tile_sizer.dart",
"src/widgets/tile_tab.dart",
- "src/widgets/status_bar_visualizer.dart"
+ "src/widgets/status_tick_bar_visualizer.dart",
+ "src/widgets/status_progress_bar_visualizer.dart"
]
deps = [
diff --git a/shell/ermine/lib/src/widgets/status.dart b/shell/ermine/lib/src/widgets/status.dart
index d04220d..4e8fb4f 100644
--- a/shell/ermine/lib/src/widgets/status.dart
+++ b/shell/ermine/lib/src/widgets/status.dart
@@ -8,7 +8,7 @@
import '../models/status_model.dart';
import '../utils/elevations.dart';
-import '../widgets/status_bar_visualizer.dart';
+import '../widgets/status_tick_bar_visualizer.dart';
const _listItemHeight = 35.0;
const _leadingStyle = TextStyle(
@@ -80,11 +80,14 @@
'CPU Usage',
style: _leadingStyle,
),
- title: StatusBarVisualizer(
+ title: StatusTickBarVisualizer(
barValue: model.getCpu(),
barFill: model.getCpuFill(),
barMax: model.getCpuMax(),
- barSize: 25,
+ tickMax: 25,
+ textStyle: _titleStyle,
+ textAlignment: TextAlign.left,
+ barFirst: true,
),
),
),
@@ -97,11 +100,14 @@
'Mem Usage',
style: _leadingStyle,
),
- title: StatusBarVisualizer(
+ title: StatusTickBarVisualizer(
barValue: model.getMem(),
barFill: model.getMemFill(),
barMax: model.getMemMax(),
- barSize: 25,
+ tickMax: 25,
+ textStyle: _titleStyle,
+ textAlignment: TextAlign.left,
+ barFirst: true,
),
),
),
@@ -159,4 +165,4 @@
),
);
}
-}
+}
\ No newline at end of file
diff --git a/shell/ermine/lib/src/widgets/status_bar_visualizer.dart b/shell/ermine/lib/src/widgets/status_bar_visualizer.dart
deleted file mode 100644
index da273b9..0000000
--- a/shell/ermine/lib/src/widgets/status_bar_visualizer.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2019 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:ui';
-
-import 'package:flutter/material.dart';
-
-// Builds bar visualization given a value, fill amount, and maximum amount.
-class StatusBarVisualizer extends StatelessWidget {
- // Descriptive text displayed to the right of bar visualization.
- final String _barValue;
- // Amount the bar visualization will be filled.
- final double _barFill;
- // Maximum amount the bar visualization can be filled.
- final double _barMax;
- // Maximum amount of tick marks allowed to be in row.
- final int _barSize;
-
- const StatusBarVisualizer(
- {@required String barValue,
- @required double barFill,
- @required double barMax,
- @required int barSize})
- : _barValue = barValue,
- _barFill = barFill,
- _barMax = barMax,
- _barSize = barSize;
-
- @override
- Widget build(BuildContext context) {
- return Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: <Widget>[
- Text(
- _drawTicks(_activeTicks()),
- style: TextStyle(
- color: Colors.white,
- fontSize: 14,
- letterSpacing: -4,
- fontFamily: 'RobotoMono',
- fontWeight: FontWeight.w400,
- ),
- ),
- Text(
- _drawTicks(_inactiveTicks()),
- style: TextStyle(
- color: Colors.grey[600],
- fontSize: 14,
- letterSpacing: -4,
- fontFamily: 'RobotoMono',
- fontWeight: FontWeight.w400,
- ),
- ),
- SizedBox(width: _barSpace()),
- Text(
- _barValue,
- textAlign: TextAlign.right,
- style: TextStyle(
- color: Colors.white,
- fontSize: 14,
- fontFamily: 'RobotoMono',
- fontWeight: FontWeight.w400,
- ),
- ),
- ],
- );
- }
-
- // Determines how many active ticks to be drawn.
- int _activeTicks() => ((_barFill / _barMax) * _maxTicks()).toInt();
-
- // Determines how many inactive ticks to be drawn.
- int _inactiveTicks() => (_maxTicks() - _activeTicks());
-
- // Determines how many ticks can fit in row.
- int _maxTicks() => _barSize - _barValue.length;
-
- // Builds string of ticks.
- String _drawTicks(int numTicks) => List.filled(numTicks + 1, '').join('| ');
-
- // Adds space to align bar visualizations.
- double _barSpace() => _barValue.length % 2 == 0 ? 9 : 6;
-}
diff --git a/shell/ermine/lib/src/widgets/status_progress_bar_visualizer.dart b/shell/ermine/lib/src/widgets/status_progress_bar_visualizer.dart
new file mode 100644
index 0000000..92ff49a
--- /dev/null
+++ b/shell/ermine/lib/src/widgets/status_progress_bar_visualizer.dart
@@ -0,0 +1,130 @@
+// Copyright 2019 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:ui';
+
+import 'package:flutter/material.dart';
+
+// Builds bar visualization given a value, fill amount, and maximum amount.
+class StatusProgressBarVisualizer extends StatelessWidget {
+ // Descriptive text displayed on the side of the progress bar visualization.
+ final String _barValue;
+ // Amount the progress bar visualization will be filled.
+ final double _barFill;
+ // Maximum amount the progress bar visualization can be filled.
+ final double _barMax;
+ // Double between 0 - 1 that determines the ratio of bar to text in container.
+ final double _barSize;
+ // Height of bar visualization & text.
+ final double _barHeight;
+ // Determines style of text in visualiation.
+ final TextStyle _textStyle;
+ // Determines alignment of text on the side of the bar visualization.
+ final TextAlign _textAlignment;
+ // Determines if bar visualization is first in order in row.
+ final bool _barFirst;
+
+ const StatusProgressBarVisualizer(
+ {@required String barValue,
+ @required double barFill,
+ @required double barMax,
+ @required double barSize,
+ @required double barHeight,
+ @required TextStyle textStyle,
+ @required TextAlign textAlignment,
+ @required bool barFirst})
+ : _barValue = barValue,
+ _barFill = barFill,
+ _barMax = barMax,
+ _barSize = barSize,
+ _barHeight = barHeight,
+ _textStyle = textStyle,
+ _textAlignment = textAlignment,
+ _barFirst = barFirst;
+
+ @override
+ Widget build(BuildContext context) {
+ if (_barFirst)
+ return _buildBarLeft(context);
+ return _buildBarRight(context);
+ }
+
+ Widget _buildBarLeft(BuildContext context) {
+ return Flex(
+ direction: Axis.horizontal,
+ children: <Widget>[
+ // Progress Bar
+ Expanded(
+ flex: (_barSize * 100).toInt(),
+ child: Flex(
+ direction: Axis.horizontal,
+ children: <Widget>[
+ Expanded(
+ flex: ((_barFill / _barMax) * 100).toInt(),
+ child: Container(
+ height: _barHeight,
+ color: Colors.white,
+ )),
+ Expanded(
+ flex: (((_barMax - _barFill) / _barMax) * 100).toInt(),
+ child: Container(
+ height: _barHeight,
+ color: Colors.grey[600],
+ ),
+ ),
+ ],
+ ),
+ ),
+ // Descriptive Text
+ Expanded(
+ flex: ((1 - _barSize) * 100).toInt(),
+ child: Text(
+ _barValue,
+ textAlign: _textAlignment,
+ style: _textStyle,
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget _buildBarRight(BuildContext context) {
+ return Flex(
+ direction: Axis.horizontal,
+ children: <Widget>[
+ // Descriptive Text
+ Expanded(
+ flex: ((1 - _barSize) * 100).toInt(),
+ child: Text(
+ _barValue,
+ textAlign: _textAlignment,
+ style: _textStyle,
+ ),
+ ),
+ // Progress Bar
+ Expanded(
+ flex: (_barSize * 100).toInt(),
+ child: Flex(
+ direction: Axis.horizontal,
+ children: <Widget>[
+ Expanded(
+ flex: ((_barFill / _barMax) * 100).toInt(),
+ child: Container(
+ height: _barHeight,
+ color: Colors.white,
+ )),
+ Expanded(
+ flex: (((_barMax - _barFill) / _barMax) * 100).toInt(),
+ child: Container(
+ height: _barHeight,
+ color: Colors.grey[600],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/shell/ermine/lib/src/widgets/status_tick_bar_visualizer.dart b/shell/ermine/lib/src/widgets/status_tick_bar_visualizer.dart
new file mode 100644
index 0000000..4fea0fb
--- /dev/null
+++ b/shell/ermine/lib/src/widgets/status_tick_bar_visualizer.dart
@@ -0,0 +1,126 @@
+// Copyright 2019 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:ui';
+
+import 'package:flutter/material.dart';
+
+// Builds bar visualization given a value, fill amount, and maximum amount.
+class StatusTickBarVisualizer extends StatelessWidget {
+ // Descriptive text displayed to the right of bar visualization.
+ final String _barValue;
+ // Amount the bar visualization will be filled.
+ final double _barFill;
+ // Maximum amount the bar visualization can be filled.
+ final double _barMax;
+ // Maximum amount of tick marks allowed to be in row.
+ final int _tickMax;
+ // Determines style of text in visualiation.
+ final TextStyle _textStyle;
+ // Determines alignment of text on the side of the bar visualization.
+ final TextAlign _textAlignment;
+ // Determines if bar visualization is first in order in row.
+ final bool _barFirst;
+
+ const StatusTickBarVisualizer(
+ {@required String barValue,
+ @required double barFill,
+ @required double barMax,
+ @required int tickMax,
+ @required TextStyle textStyle,
+ @required TextAlign textAlignment,
+ @required bool barFirst})
+ : _barValue = barValue,
+ _barFill = barFill,
+ _barMax = barMax,
+ _tickMax = tickMax,
+ _textStyle = textStyle,
+ _textAlignment = textAlignment,
+ _barFirst = barFirst;
+
+ @override
+ Widget build(BuildContext context) {
+ if (_barFirst)
+ return _buildBarLeft(context);
+ return _buildBarRight(context);
+ }
+
+ Widget _buildBarLeft(BuildContext context) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: <Widget>[
+ Text(
+ _drawTicks(_activeTicks()),
+ style: _setTickStyle(true)
+ ),
+ Text(
+ _drawTicks(_inactiveTicks()),
+ style: _setTickStyle(false),
+ ),
+ SizedBox(width: _barSpace()),
+ Text(
+ _barValue,
+ textAlign: _textAlignment,
+ style: _textStyle,
+ ),
+ ],
+ );
+ }
+
+ Widget _buildBarRight(BuildContext context) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: <Widget>[
+ Text(
+ _barValue,
+ textAlign: _textAlignment,
+ style: _textStyle,
+ ),
+ SizedBox(width: _barSpace()),
+ Text(
+ _drawTicks(_activeTicks()),
+ style: _setTickStyle(true),
+ ),
+ Text(
+ _drawTicks(_inactiveTicks()),
+ style: _setTickStyle(false)
+ ),
+ ],
+ );
+ }
+
+ TextStyle _setTickStyle(bool active) {
+ if (active) {
+ return TextStyle(
+ color: Colors.white,
+ fontSize: 14,
+ letterSpacing: -4,
+ fontFamily: 'RobotoMono',
+ fontWeight: FontWeight.w400,
+ );
+ }
+ return TextStyle(
+ color: Colors.grey[600],
+ fontSize: 14,
+ letterSpacing: -4,
+ fontFamily: 'RobotoMono',
+ fontWeight: FontWeight.w400,
+ );
+ }
+
+ // Determines how many active ticks to be drawn.
+ int _activeTicks() => ((_barFill / _barMax) * _maxTicks()).toInt();
+
+ // Determines how many inactive ticks to be drawn.
+ int _inactiveTicks() => (_maxTicks() - _activeTicks());
+
+ // Determines how many ticks can fit in row.
+ int _maxTicks() => _tickMax - _barValue.length;
+
+ // Builds string of ticks.
+ String _drawTicks(int numTicks) => List.filled(numTicks + 1, '').join('| ');
+
+ // Adds space to align bar visualizations.
+ double _barSpace() => _barValue.length % 2 == 0 ? 9 : 6;
+}