Untitled
unknown
plain_text
a year ago
17 kB
22
Indexable
import 'package:flutter/material.dart';
class SandConeCalculator extends StatefulWidget {
@override
_SandConeCalculatorState createState() => _SandConeCalculatorState();
}
class _SandConeCalculatorState extends State<SandConeCalculator> {
// Constants
final int numberOfTests = 10;
// Common input controllers
final TextEditingController sandDensityController = TextEditingController();
final TextEditingController mddController = TextEditingController();
// Input controllers for cone weights (for cones 1 to 5)
List<TextEditingController> coneWeightControllers = [];
// Input controllers for test-specific inputs
List<TextEditingController> coneNumberControllers = [];
List<TextEditingController> weightBeforeControllers = [];
List<TextEditingController> weightAfterControllers = [];
List<TextEditingController> weightHoleControllers = [];
List<TextEditingController> waterContentControllers = [];
// Output variables for 10 tests
List<double> rdPercentages = [];
@override
void initState() {
super.initState();
// Initialize controllers for cone weights (cones 1 to 5)
for (int i = 0; i < 5; i++) {
coneWeightControllers.add(TextEditingController());
}
// Initialize controllers and RD% list for test-specific inputs
for (int i = 0; i < numberOfTests; i++) {
coneNumberControllers.add(TextEditingController());
weightBeforeControllers.add(TextEditingController());
weightAfterControllers.add(TextEditingController());
weightHoleControllers.add(TextEditingController());
waterContentControllers.add(TextEditingController());
rdPercentages.add(0); // Initialize each RD% with 0
}
}
// Function to perform the calculations for each test
void calculateCompaction(int index) {
// Parsing common inputs
double s = double.tryParse(sandDensityController.text) ?? 0;
double MDD = double.tryParse(mddController.text) ?? 0;
// Parsing test-specific inputs
int coneNumber = int.tryParse(coneNumberControllers[index].text) ?? 0;
double C = (coneNumber >= 1 && coneNumber <= 5)
? double.tryParse(coneWeightControllers[coneNumber - 1].text) ?? 0
: 0; // Fetch cone weight from the input for that cone number
double w1 = double.tryParse(weightBeforeControllers[index].text) ?? 0;
double w2 = double.tryParse(weightAfterControllers[index].text) ?? 0;
double w3 = double.tryParse(weightHoleControllers[index].text) ?? 0;
double wc = double.tryParse(waterContentControllers[index].text) ?? 0;
if (s == 0 || MDD == 0 || C == 0) {
setState(() {
rdPercentages[index] = 0; // Avoid dividing by zero
});
return;
}
// Calculations
double dryWeightHole = w3 * (100 - wc) / 100;
double weightSandFillHole = w1 - w2 - C;
double holeVolume = weightSandFillHole / s;
double wetDensity = w3 / holeVolume;
double moistPercent = (w3 - dryWeightHole) / dryWeightHole * 100;
double dryDensity = wetDensity / (1 + moistPercent / 100);
// RD% Calculation
setState(() {
rdPercentages[index] = (dryDensity / MDD) * 100;
});
}
// This function triggers the calculation on input change for a specific test
void onInputChanged(int index) {
calculateCompaction(index);
}
// Function to clear all test inputs
void clearTestInputs() {
for (int i = 0; i < numberOfTests; i++) {
coneNumberControllers[i].clear();
weightBeforeControllers[i].clear();
weightAfterControllers[i].clear();
weightHoleControllers[i].clear();
waterContentControllers[i].clear();
rdPercentages[i] = 0; // Reset RD%
}
setState(() {}); // Update the UI
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(
'Sand Cone Calculator - by M.A.Elnaggar',
style: TextStyle(fontSize: 12), // Font size set to 12
),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Common Inputs for all tests
Text(
'Common Input Fields:',
style: TextStyle(
fontSize: 12,
fontFamily: 'Times New Roman',
),
),
Table(
columnWidths: {
0: FixedColumnWidth(200), // Fixed width for labels
1: FlexColumnWidth(), // Flexible width for inputs
},
children: [
TableRow(
children: [
Text(
'Sand Density (s): ',
style: TextStyle(
fontSize: 12,
fontFamily: 'Times New Roman',
),
),
TextField(
controller: sandDensityController,
decoration: InputDecoration(hintText: 'Enter sand density'),
keyboardType: TextInputType.number,
onChanged: (_) {
// Recalculate all tests when common values change
for (int i = 0; i < numberOfTests; i++) {
calculateCompaction(i);
}
},
),
],
),
TableRow(
children: [
Text(
'Max Dry Density (MDD): ',
style: TextStyle(
fontSize: 12,
fontFamily: 'Times New Roman',
),
),
TextField(
controller: mddController,
decoration: InputDecoration(hintText: 'Enter max dry density'),
keyboardType: TextInputType.number,
onChanged: (_) {
for (int i = 0; i < numberOfTests; i++) {
calculateCompaction(i);
}
},
),
],
),
],
),
SizedBox(height: 20),
// Input fields for cone weights (1-5)
Text(
'Cone Weights (Enter weights for cones 1 to 5):',
style: TextStyle(
fontSize: 12,
fontFamily: 'Times New Roman',
),
),
SizedBox(height: 10), // Optional: Add space before the row
Row(
mainAxisAlignment: MainAxisAlignment.start, // Align to the start
children: [
for (int i = 0; i < 5; i++)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0), // Space between inputs
child: Column(
children: [
Text(
'Cone ${i + 1}:',
style: TextStyle(
fontSize: 12,
fontFamily: 'Times New Roman',
),
),
SizedBox(height: 5), // Optional: Space between label and text field
SizedBox(
width: 50, // Set a fixed width for the text field
child: TextField(
controller: coneWeightControllers[i],
decoration: InputDecoration(hintText: ''),
keyboardType: TextInputType.number,
onChanged: (_) {
// Recalculate all tests when cone weights change
for (int j = 0; j < numberOfTests; j++) {
calculateCompaction(j);
}
},
),
),
],
),
),
],
),
SizedBox(height: 20),
// Test-specific inputs in one unified table
Text(
'Test points:',
style: TextStyle(
fontSize: 12,
fontFamily: 'Times New Roman',
),
),
Table(
border: TableBorder.all(color: Colors.black), // Add borders around the table
columnWidths: {
0: FlexColumnWidth(0.5),
1: FlexColumnWidth(0.5),
2: FlexColumnWidth(),
3: FlexColumnWidth(),
4: FlexColumnWidth(),
5: FlexColumnWidth(),
6: FlexColumnWidth(0.8),
},
children: [
// Table header
TableRow(
decoration: BoxDecoration(color: Color.fromARGB(150, 155, 232, 235)), // Header background color
children: [
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for header
child: Text(
'# Point',
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), // Font size and weight for header
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for header
child: Text(
'Cone #',
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), // Font size and weight for header
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for header
child: Text(
'Weight Before (w1)',
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), // Font size and weight for header
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for header
child: Text(
'Weight After (w2)',
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), // Font size and weight for header
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for header
child: Text(
'Weight of Hole (w3)',
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), // Font size and weight for header
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for header
child: Text(
'Water Content (wc)',
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), // Font size and weight for header
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for header
child: Text(
'RD%',
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold), // Font size and weight for header
),
),
],
),
// Input rows
for (int i = 0; i < numberOfTests; i++)
TableRow(
children: [
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for row
child: Text(
(i + 1).toString(),
style: TextStyle(fontSize: 12),
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for row
child: TextField(
controller: coneNumberControllers[i],
keyboardType: TextInputType.number,
onChanged: (_) => onInputChanged(i),
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for row
child: TextField(
controller: weightBeforeControllers[i],
keyboardType: TextInputType.number,
onChanged: (_) => onInputChanged(i),
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for row
child: TextField(
controller: weightAfterControllers[i],
keyboardType: TextInputType.number,
onChanged: (_) => onInputChanged(i),
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for row
child: TextField(
controller: weightHoleControllers[i],
keyboardType: TextInputType.number,
onChanged: (_) => onInputChanged(i),
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for row
child: TextField(
controller: waterContentControllers[i],
keyboardType: TextInputType.number,
onChanged: (_) => onInputChanged(i),
),
),
Padding(
padding: const EdgeInsets.all(4.0), // Adjust padding for row
child: Text(
rdPercentages[i].toStringAsFixed(2),
style: TextStyle(fontSize: 12),
),
),
],
),
],
),
SizedBox(height: 20),
// Button to clear all inputs
Center(
child: ElevatedButton(
onPressed: clearTestInputs,
child: Text('Clear All Inputs'),
),
),
],
),
),
),
),
);
}
@override
void dispose() {
// Dispose controllers
for (var controller in coneWeightControllers) {
controller.dispose();
}
for (int i = 0; i < numberOfTests; i++) {
coneNumberControllers[i].dispose();
weightBeforeControllers[i].dispose();
weightAfterControllers[i].dispose();
weightHoleControllers[i].dispose();
waterContentControllers[i].dispose();
}
sandDensityController.dispose();
mddController.dispose();
super.dispose();
}
}
void main() {
runApp(SandConeCalculator());
}
Editor is loading...
Leave a Comment