flutter_thermometer 1.0.0 flutter_thermometer: ^1.0.0 copied to clipboard
A thermometer widget for Flutter
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
import 'package:flutter_thermometer/thermometer.dart';
import 'custom_scale_provider.dart';
void main() => runApp(ThermometerDemoApp());
class ThermometerDemoApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ThermometerDemoWrapper(),
);
}
}
class ThermometerDemoWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) => ThermometerDemo();
}
class ThermometerDemo extends StatefulWidget {
@override
_ThermometerDemoState createState() => _ThermometerDemoState();
}
class _ThermometerDemoState extends State<ThermometerDemo>
with TickerProviderStateMixin {
bool fullscreen;
double thermoWidth;
double thermoHeight;
double minValue;
double maxValue;
double value;
double radius;
double barWidth;
double outlineThickness;
Color outlineColor;
Color mercuryColor;
Color backgroundColor;
bool useCustomScale;
double scaleInterval;
bool mirrorScale;
int labelType; // 0 - Celsius; 1 - Farenheit; 2 - Custom
bool setpointEnabled;
Setpoint setpoint;
@override
void initState() {
fullscreen = false;
thermoHeight = 150;
thermoWidth = 150;
minValue = -10;
maxValue = 70;
value = 30;
radius = 30.0;
barWidth = 30.0;
outlineThickness = 5.0;
outlineColor = Colors.black;
mercuryColor = Colors.red;
backgroundColor = Colors.transparent;
useCustomScale = false;
scaleInterval = 10;
mirrorScale = false;
labelType = 0;
setpointEnabled = false;
setpoint =
Setpoint(60, size: 9, color: Colors.blue, side: SetpointSide.both);
super.initState();
}
@override
Widget build(BuildContext context) {
final tabController =
TabController(length: 5, initialIndex: 0, vsync: this);
return Scaffold(
appBar: AppBar(
title: Text('Thermometer Demo'),
),
body: fullscreen
? Center(child: _buildDUT())
: Column(
children: <Widget>[
Container(
height: 300,
child: Center(
child: _buildDUT(),
),
),
Container(
child: _buildSettings(tabController),
)
],
));
}
Widget _buildDUT() => GestureDetector(
child: SizedBox(
width: thermoWidth,
height: thermoHeight,
child: Thermometer(
value: value,
minValue: minValue,
maxValue: maxValue,
radius: radius,
barWidth: barWidth,
outlineThickness: outlineThickness,
outlineColor: outlineColor,
mercuryColor: mercuryColor,
backgroundColor: backgroundColor,
scale: useCustomScale
? CustomScaleProvider()
: IntervalScaleProvider(scaleInterval),
mirrorScale: mirrorScale,
label: labelType == 0
? ThermometerLabel.celsius()
: labelType == 1
? ThermometerLabel.farenheit()
: ThermometerLabel('Custom',
textStyle: TextStyle(
color: Colors.blue,
fontSize: 16,
fontStyle: FontStyle.italic)),
setpoint: setpointEnabled ? setpoint : null),
),
onTap: () {
setState(() {
fullscreen = !fullscreen;
});
},
);
Widget _buildSettings(TabController tabController) => Column(
children: <Widget>[
Container(
child: TabBar(
labelColor: Colors.black,
controller: tabController,
tabs: <Widget>[
Tab(
child: Text('Value'),
),
Tab(text: 'Colors'),
Tab(text: 'Geometry'),
Tab(text: 'Scale'),
Tab(text: 'Setpoint')
],
),
),
Container(
height: 250,
child: TabBarView(
controller: tabController,
children: <Widget>[
_buildValueTab(),
_buildColorTab(),
_buildGeometryTab(),
_buildScaleTab(),
_buildSetpointTab()
],
),
)
],
);
Widget _buildValueTab() {
return Table(
columnWidths: {0: FixedColumnWidth(100)},
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(children: [
Text('Min Value'),
Slider(
min: -100,
max: 100,
value: minValue,
onChanged: (sliderValue) {
setState(() {
minValue = min(sliderValue, maxValue - 10);
value = max(value, minValue);
setpoint.apply(value: max(setpoint.value, minValue));
});
})
]),
TableRow(children: [
Text('Max Value'),
Slider(
min: -100,
max: 100,
value: maxValue,
onChanged: (sliderValue) {
setState(() {
maxValue = max(sliderValue, minValue + 10);
value = min(value, maxValue);
setpoint.apply(value: min(setpoint.value, maxValue));
});
},
)
]),
TableRow(children: [
Text('Value'),
Slider(
min: -100,
max: 100,
value: value,
onChanged: (sliderValue) {
setState(() {
value = max(min(sliderValue, maxValue), minValue);
});
},
)
])
],
);
}
Widget _buildColorTab() {
return Table(
columnWidths: {0: FixedColumnWidth(100)},
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(children: [
Text('Outline'),
CircleColor(
color: outlineColor,
circleSize: 35.0,
onColorChoose: () {
colorPickerDialog(context, outlineColor).then((newColor) {
if (newColor != null)
setState(() {
outlineColor = newColor;
});
});
},
)
]),
TableRow(children: [
Text('Mercury'),
CircleColor(
circleSize: 35.0,
color: mercuryColor,
onColorChoose: () {
colorPickerDialog(context, mercuryColor).then((newColor) {
if (newColor != null)
setState(() {
mercuryColor = newColor;
});
});
})
]),
TableRow(children: [
Text('Backgound'),
CircleColor(
circleSize: 35.0,
color: backgroundColor,
onColorChoose: () {
colorPickerDialog(context, backgroundColor).then((newColor) {
if (newColor != null)
setState(() {
backgroundColor = newColor;
});
});
})
])
],
);
}
Widget _buildGeometryTab() {
return Table(
columnWidths: {0: FixedColumnWidth(100)},
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(children: [
Text('Height'),
Slider(
min: 50,
max: 300,
value: thermoHeight,
onChanged: (sliderValue) {
setState(() {
thermoHeight = sliderValue;
});
})
]),
TableRow(children: [
Text('Width'),
Slider(
min: 50,
max: 300,
value: thermoWidth,
onChanged: (sliderValue) {
setState(() {
thermoWidth = sliderValue;
});
},
)
]),
TableRow(children: [
Text('Thickness'),
Slider(
min: 1,
max: 10,
value: outlineThickness,
onChanged: (sliderValue) {
setState(() {
outlineThickness = sliderValue;
});
},
)
]),
TableRow(children: [
Text('Bar Width'),
Slider(
min: 10,
max: 40,
value: barWidth,
onChanged: (sliderValue) {
setState(() {
barWidth = sliderValue;
radius = max(radius, barWidth);
});
},
)
]),
TableRow(children: [
Text('Radius'),
Slider(
min: 10,
max: 40,
value: radius,
onChanged: (sliderValue) {
setState(() {
radius = sliderValue;
barWidth = min(radius, barWidth);
});
},
)
])
],
);
}
Widget _buildScaleTab() {
return Table(
columnWidths: {0: FixedColumnWidth(70)},
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(children: [
Text('Scale Type'),
Row(
children: <Widget>[
Row(children: <Widget>[
Radio(
value: true,
groupValue: useCustomScale,
onChanged: (v) {
setState(() {
useCustomScale = true;
});
}),
Text('Custom')
]),
Row(
children: <Widget>[
Radio(
value: false,
groupValue: useCustomScale,
onChanged: (v) {
setState(() {
useCustomScale = false;
});
}),
Text('Interval')
],
)
],
)
]),
TableRow(children: [
Text('Interval'),
Slider(
min: 5,
max: 20,
value: scaleInterval,
onChanged: useCustomScale
? null
: (sliderValue) {
setState(() {
scaleInterval = sliderValue;
});
},
)
]),
TableRow(children: [
Text('Mirror'),
Checkbox(
value: mirrorScale,
onChanged: (v) {
setState(() {
mirrorScale = v;
});
},
)
]),
TableRow(children: [
Text('Label'),
Row(
children: <Widget>[
Row(
children: <Widget>[
Radio(
value: 0,
groupValue: labelType,
onChanged: (v) {
setState(() {
labelType = v;
});
},
),
Text('Celsius')
],
),
Row(
children: <Widget>[
Radio(
value: 1,
groupValue: labelType,
onChanged: (v) {
setState(() {
labelType = v;
});
}),
Text('Farenheit')
],
),
Row(
children: <Widget>[
Radio(
value: 2,
groupValue: labelType,
onChanged: (v) {
setState(() {
labelType = v;
});
}),
Text('Custom')
],
)
],
)
])
]);
}
Widget _buildSetpointTab() {
return Table(
columnWidths: {0: FixedColumnWidth(70)},
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(children: [
Text('Enabled'),
Checkbox(
value: setpointEnabled,
onChanged: (v) {
setState(() {
setpointEnabled = true;
});
},
)
]),
TableRow(children: [
Text('Value'),
Slider(
min: minValue,
max: maxValue,
value: setpoint.value,
onChanged: (sliderValue) {
setState(() {
setpoint = setpoint.apply(value: sliderValue);
});
},
)
]),
TableRow(children: [
Text('Size'),
Slider(
min: 5,
max: 20,
value: setpoint.size,
onChanged: useCustomScale
? null
: (sliderValue) {
setState(() {
setpoint = setpoint.apply(size: sliderValue);
});
},
)
]),
TableRow(children: [
Text('Color'),
CircleColor(
circleSize: 35.0,
color: setpoint.color,
onColorChoose: () {
colorPickerDialog(context, setpoint.color).then((newColor) {
if (newColor != null)
setState(() {
setpoint = setpoint.apply(color: newColor);
});
});
})
]),
TableRow(children: [
Text('Side'),
Row(
children: <Widget>[
Row(
children: <Widget>[
Radio(
value: SetpointSide.left,
groupValue: setpoint.side,
onChanged: (v) {
setState(() {
setpoint = setpoint.apply(side: v);
});
},
),
Text('Left')
],
),
Row(
children: <Widget>[
Radio(
value: SetpointSide.right,
groupValue: setpoint.side,
onChanged: (v) {
setState(() {
setpoint = setpoint.apply(side: v);
});
}),
Text('Right')
],
),
Row(
children: <Widget>[
Radio(
value: SetpointSide.both,
groupValue: setpoint.side,
onChanged: (v) {
setState(() {
setpoint = setpoint.apply(side: v);
});
}),
Text('Both')
],
)
],
)
])
]);
}
}
Future<Color> colorPickerDialog(BuildContext context, Color oldColor) {
Color selectedColor = oldColor;
return showDialog<Color>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('Pick a color'),
contentPadding: EdgeInsets.all(6.0),
content: MaterialColorPicker(
allowShades: false,
selectedColor: selectedColor,
onMainColorChange: (c) {
selectedColor = c;
},
),
actions: <Widget>[
FlatButton(
child: Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop(selectedColor);
},
)
],
));
}