Commit 1047600b authored by Meade's avatar Meade

Added version 5.0.0. See README.md for the full update list.

parent 0c2a1f0e
# Maintainer: Meade And Emily <thedarkula2049@gmail.com>
pkgname=brewstillery
pkgver=3.0.0
pkgver=5.0.0
pkgrel=1
pkgdesc="BrewStillery is a brewer's, vintner's, and distiller's calculator. It has a multitude of great functions, such as calculating ABV, determining carbonation, and total sparge water needed."
url="https://monkeylog.in"
arch=('i686' 'x86_64')
license=('AGPL3')
depends=('ttf-roboto')
makedepends=('git' 'cargo')
provides=('brewstillery')
conflicts=('brewstillery')
source=("https://github.com/MonkeyLog/BrewStillery/archive/$pkgver.tar.gz")
md5sums=('SKIP')
md5sums=('7050dfdbe6f43fe25455dc63b9472af7')
build() {
cd $srcdir/BrewStillery-$pkgver
......@@ -25,4 +26,10 @@ package() {
cd $srcdir/BrewStillery-$pkgver/media
install -Dm755 BrewStilleryIcon.svg "$pkgdir/usr/share/BrewStillery/BrewStilleryIcon.svg"
install -Dm755 BrewStilleryLogo.svg "$pkgdir/usr/share/BrewStillery/BrewStilleryLogo.svg"
cd $srcdir/BrewStillery-$pkgver/media/glassware
install -Dm755 /usr/share/BrewStillery/glassware
install -Dm755 *.png "$pkgdir/usr/share/BrewStillery/glassware/"
cd $srcdir/BrewStillery-$pkgver/media/buttons
install -Dm755 /usr/share/BrewStillery/buttons
install -Dm755 *.png "$pkgdir/usr/share/BrewStillery/buttons/"
}
\ No newline at end of file
This diff is collapsed.
[package]
name = "BrewStillery"
version = "3.0.0"
authors = ["Emily And Meade <thedarkula2049@gmail.com>"]
version = "5.0.0"
authors = ["Meade <thedarkula2049@gmail.com>", "Emily <marleybrush5@gmail.com>"]
description = "BrewStillery is a brewer's, vintner's, and distiller's calculator. It has a multitude of great functions, such as calculating ABV, determining carbonation, and total sparge water needed."
# documentation to come
# documentation = "..."
......@@ -11,21 +11,27 @@ readme = "README.md"
keywords = ["beer", "wine", "champagne", "distilling", "calculator"]
categories = ["science", "gui"]
license = "AGPL-3.0"
exclude = ["media/screenshots/*", "Arch/*"]
exclude = ["Arch/*"]
[badges]
maintenance = { status = "actively-developed" }
[dependencies]
gdk = "0.7.0"
gio = "0.3.0"
clippy = {version = "*", optional = true}
[features]
default = []
[dependencies.gtk]
version = "0.2.0"
version = "0.3.0"
features = ["v3_22"]
[profile.dev]
codegen-units = 4
codegen-units = 16
[profile.release]
opt-level = 3
codegen-units = 4
codegen-units = 16
lto = true
\ No newline at end of file
......@@ -4,10 +4,20 @@ It has a multitude of great functions, such as calculating ABV, determining carb
Written in Rust, using GTK3
## New In 3.0.0
Added the grain calculator to the beer tab.
Reworked the maths in the RealABV calculator, because it was completely inaccurate.
Reworked the graphical layout as well.
## New In 5.0.0
* MASSIVE overhaul!!! Hence the jump from Version 3.0.0 to 5.0.0.
* Huge code cleanup: removed tons of unneeded borrows and things of that nature.
* Created a complete theme with CSS and images.
* Switched from a GtkWindow to a GtkApplicationWindow, which allows us to have proper domain naming.
* Added finished beer colour output:
* To calculate what the finished beer will look like, the flow goes like this:
* Individual grains go through singleMCU, those are added up and passed into beerSRM, and that gives us a total SRM value.
* We then convert that SRM value to L\*ab, from L\*ab to XYZ, and finally to RGBA.
* That gives us the colour you would expect to see.
* Also, because of the diameter of a glass, larger vessels will make beer appear darker. So, we accounted for that with standard glassware and averaged lighting data.
* We now have a dropdown menu where you can pick your glassware and it will show you the appropriate colour in that glass.
* Switched from an entry/button setup to a dynamic one: everything is calculated on the fly.
* Refactored our ABV functions. It's now based off of one source, which is very accurate.
## Screenshots:
......@@ -23,15 +33,16 @@ Reworked the graphical layout as well.
## To Do:
* Water Minerals
* Export To Gourmet
* Update Screenshots
* Add Documentation To The Info Tab
* Add Sugars And Fruits To ABV From Grain
* Add Water Minerals Calculator
* Add Export To Gourmet Option
## Building:
To install on Arch, the AUR package name is ```brewstillery```.
In Cargo.toml, set ```codegen-units``` to however many cores you want to use to compile.
To build, just run ```cargo build --release```. The resultant binary will be ```target/release/BrewStillery```.
To install/uninstall system-wide, run ```install.sh``` or ```uninstall.sh``` from the scripts directory.
......@@ -45,7 +56,11 @@ Reworked the graphical layout as well.
## Sources:
* ["Brew By Numbers - Add Up What's In Your Beer"](https://www.homebrewersassociation.org/attachments/0000/2497/Math_in_Mash_SummerZym95.pdf) - Michael L. Hall. PH.D., Zymurgy (Summer) 1995
* ["Refractometer FG Results « SeanTerrill.com"](http://seanterrill.com/2011/04/07/refractometer-fg-results/) - SeanTerrill.com, Modified: January 2010
* ["Kraeusening"](http://www.braukaiser.com/wiki/index.php?title=Kraeusening) - Braukaiser.com, Modified: January 2, 2010
* ["Glenn Tinseth's Hop Page"](http://realbeer.com/hops/) - Glenn Tinseth, 1995-1999
* ["Calculating Gravity, Bitterness, And Color: Techniques"](https://byo.com/bock/item/409-calculating-gravity-bitterness-and-color-techniques) - Glenn Tinseth, 1995-1999
* ["Formulas And C Source Code"](https://web.archive.org/web/20090807084643/http://www.primetab.com:80/formulas) - PrimeTab, Modified: March 25, 2002
\ No newline at end of file
* ["Calculating Gravity, Bitterness, And Color: Techniques"](https://byo.com/bock/item/409-calculating-gravity-bitterness-and-color-techniques) - Chris Colby, 2000
* ["Formulas And C Source Code"](https://web.archive.org/web/20090807084643/http://www.primetab.com:80/formulas) - PrimeTab, Modified: March 25, 2002
* ["Estimating Color"](http://brewwiki.com/index.php/Estimating_Color) - BrewWiki.com, Modified: May, 17 2008
* ["Technical Information for Brewers"](http://wetnewf.org/pdfs/Brewing_articles/MOAWorkbook.xls) - A.J. deLange, 2013
* ["Color math and programming code examples"](https://www.easyrgb.com/en/math.php) - IRO Group Limited, 2018
\ No newline at end of file
......@@ -4,4 +4,8 @@ cargo build --release &&
sudo install -Dm755 ../target/release/BrewStillery /usr/bin/BrewStillery &&
sudo install -Dm755 ../Arch/BrewStillery.desktop /usr/share/applications/BrewStillery.desktop &&
sudo install -Dm755 ../media/BrewStilleryIcon.svg /usr/share/BrewStillery/BrewStilleryIcon.svg &&
sudo install -Dm755 ../media/BrewStilleryLogo.svg /usr/share/BrewStillery/BrewStilleryLogo.svg
\ No newline at end of file
sudo install -Dm755 ../media/BrewStilleryLogo.svg /usr/share/BrewStillery/BrewStilleryLogo.svg &&
sudo install -Dm755 /usr/share/BrewStillery/glassware &&
sudo install -Dm755 ../media/glassware/*.png /usr/share/BrewStillery/glassware/ &&
sudo install -Dm755 /usr/share/BrewStillery/buttons &&
sudo install -Dm755 ../media/buttons/*.png /usr/share/BrewStillery/buttons/
\ No newline at end of file
......@@ -2,40 +2,36 @@ use gtk;
use gtk::prelude::*;
use functions::commonFunctions::*;
pub fn champagneCarbonationPrep(ref champagneCarbonationBuilderClone: &gtk::Builder) {
let champagneCarbonationInput: &gtk::Entry = &champagneCarbonationBuilderClone.get_object("champagneCarbonationInput").unwrap();
pub fn champagneCarbonationPrep(champagneCarbonationBuilderClone: &gtk::Builder) {
let champagneCarbonationInput: gtk::Entry = champagneCarbonationBuilderClone.get_object("champagneCarbonationInput").unwrap();
let champagneCarbonationInputBuffer = champagneCarbonationInput.get_text().expect("No input");
let champagneVolume = validInput(&champagneCarbonationInputBuffer);
let champagneCarbonationOutput = String::from("champagneCarbonationOutput");
let champagneCarbonationOutput: gtk::Entry = champagneCarbonationBuilderClone.get_object("champagneCarbonationOutput").unwrap();
if champagneVolume == 0.0 {
let output: gtk::Entry = champagneCarbonationBuilderClone.get_object(&champagneCarbonationOutput).unwrap();
output.set_text("Enter a number");
champagneCarbonationOutput.set_text("Enter a number");
} else if champagneVolume <= 0.0 {
champagneCarbonationOutput.set_text("Enter a positive number");
} else {
if champagneVolume <= 0.0 {
let output: gtk::Entry = champagneCarbonationBuilderClone.get_object(&champagneCarbonationOutput).unwrap();
output.set_text("Enter a positive number");
} else {
onChampagneActivate(champagneVolume, &champagneCarbonationBuilderClone);
}
onChampagneActivate(champagneVolume, champagneCarbonationBuilderClone);
}
}
fn onChampagneActivate(champagneVolume: f32, ref champagneCarbonationBuilderClone: &gtk::Builder) {
let ref champagneCarbonationSwitch: &gtk::Switch = &champagneCarbonationBuilderClone.get_object("champagneCarbonationSwitch").unwrap();
fn onChampagneActivate(champagneVolume: f64, champagneCarbonationBuilderClone: &gtk::Builder) {
let champagneCarbonationSwitch: gtk::Switch = champagneCarbonationBuilderClone.get_object("champagneCarbonationSwitch").unwrap();
if champagneCarbonationSwitch.get_active() == true {
let imperialOrMetric = String::from("metric");
champagneCarbonationMaths(champagneVolume, imperialOrMetric, &champagneCarbonationBuilderClone);
let imperialOrMetric = "metric";
champagneCarbonationMaths(champagneVolume, imperialOrMetric, champagneCarbonationBuilderClone);
} else if champagneCarbonationSwitch.get_active() == false {
let imperialOrMetric = String::from("imperial");
champagneCarbonationMaths(champagneVolume, imperialOrMetric, &champagneCarbonationBuilderClone);
let imperialOrMetric = "imperial";
champagneCarbonationMaths(champagneVolume, imperialOrMetric, champagneCarbonationBuilderClone);
}
}
fn champagneCarbonationMaths(champagneVolume: f32, imperialOrMetric: String, ref champagneCarbonationBuilderClone: &gtk::Builder) {
let ref champagneCarbonationOutput: &gtk::Entry = &champagneCarbonationBuilderClone.get_object("champagneCarbonationOutput").unwrap();
fn champagneCarbonationMaths(champagneVolume: f64, imperialOrMetric: &str, champagneCarbonationBuilderClone: &gtk::Builder) {
let champagneCarbonationOutput: gtk::Entry = champagneCarbonationBuilderClone.get_object("champagneCarbonationOutput").unwrap();
if imperialOrMetric == "imperial" {
let totalSugar = champagneVolume * 0.2;
......
use std::f32::consts::E;
use std::f64::consts::E;
pub fn brixToGravity(brix: f32) -> f32 {
pub const finalGravityIdeal: f64 = 1.01627;
// when finalGravity is unknown, this constant is ideal. it is the average of all BJCP styles
pub const finalBrixIdeal: f64 = 4.1480675;
// when finalBrix is unknown, this constant is ideal. it is the average of all BJCP styles
pub fn brixToGravity(brix: f64) -> f64 {
(brix / (258.6 - ((brix / 258.2) * 227.1))) + 1.0
}
pub fn gravityToBrix(gravity: f32) -> f32 {
pub fn gravityToBrix(gravity: f64) -> f64 {
((258.6 * gravity) - 258.6) / ((0.87955073 * gravity) + 0.12044926)
}
pub fn gravityToPlato(gravity: f32) -> f32 {
pub fn gravityToPlato(gravity: f64) -> f64 {
135.997 * gravity.powi(3) - 630.272 * gravity.powi(2) + 1111.14 * gravity - 616.868
}
pub fn gramsToOunces(grams: f32) -> f32 {
0.03527396_f32 * grams
pub fn gramsToOunces(grams: f64) -> f64 {
0.03527396_f64 * grams
}
pub fn kilosToPounds(kilos: f64) -> f64 {
2.204623_f64 * kilos
}
pub fn kilosToPounds(kilos: f32) -> f32 {
2.204623_f32 * kilos
pub fn litresToGallons(litres: f64) -> f64 {
0.2641729_f64 * litres
}
pub fn litresToGallons(litres: f32) -> f32 {
0.2641729_f32 * litres
pub fn gallonsToLitres(gallons: f64) -> f64 {
3.7854_f64 * gallons
}
pub fn validInput(stringToCheck: &String) -> f32 {
let stringInput = stringToCheck.parse::<f32>();
pub fn validInput(stringToCheck: &str) -> f64 {
let stringInput = stringToCheck.parse::<f64>();
match stringInput {
Ok(number) => number,
Err(_) => 0.0,
}
}
pub fn realIBU(brix: f32, wortVolume: f32, boilTime: f32, alphaAcid: f32, hopAmount: f32) -> f32 {
(1.65 * 0.000125_f32.powf(brixToGravity(brix) - 1.0)) * ((1.0 - E.powf(-0.04 * boilTime)) / 4.15) * (( (alphaAcid / 100.0) * hopAmount * 7490.0 ) / wortVolume)
pub fn realIBU(brix: f64, wortVolume: f64, boilTime: f64, alphaAcid: f64, hopAmount: f64) -> f64 {
(1.65 * 0.000125_f64.powf(brixToGravity(brix) - 1.0)) * ((1.0 - E.powf(-0.04 * boilTime)) / 4.15) * (( (alphaAcid / 100.0) * hopAmount * 7490.0 ) / wortVolume)
}
pub fn guestimateABV(originalGravity: f32) -> f32 {
let finalGravity: f32 = 1.010;
// since finalGravity is unknown, this constant is ideal
let originalExtract = (-668.962) + (1262.45 * originalGravity ) - (776.43 * originalGravity.powi(2)) + (182.94 * originalGravity.powi(3));
let apparentExtract = (-668.962) + (1262.45 * finalGravity ) - (776.43 * finalGravity.powi(2)) + (182.94 * finalGravity.powi(3));
let attenuationCoefficient = (0.22) + (0.001 * originalExtract);
let realExtract = ((attenuationCoefficient * originalExtract) + apparentExtract) / (1.0 + attenuationCoefficient);
// unneeded information, but here if we want it
//
// let realAttenuation = ((originalExtract - realExtract) / originalExtract) * 100.0;
// let realAttenuationRounded = format!("{:.2}", realAttenuation);
// println!("Your Real Attenuation is: {}", realAttenuationRounded);
let estimatedABW = (originalExtract - realExtract) / ( 2.0665 - (0.010665 * originalExtract));
let estimatedABV = estimatedABW * (finalGravity / 0.794);
estimatedABV
pub fn realABV(startingBrix: f64, finalBrix: f64) -> (f64, f64) {
let wortCorrectionFactor: f64 = 1.040;
let initialRefractiveIndex = startingBrix / wortCorrectionFactor;
let finalRefractiveIndex = finalBrix / wortCorrectionFactor;
let newCubic = (1.0 - 0.0044992999999999995 * initialRefractiveIndex) + (0.0117741 * finalRefractiveIndex) + (0.000275806 * initialRefractiveIndex.powi(2)) - (0.00127169 * finalRefractiveIndex.powi(2)) - (7.27999e-06 * initialRefractiveIndex.powi(3)) + (6.32929e-05 * finalRefractiveIndex.powi(3));
let apparentAttenuation = 1.0 - (0.18080000000000002 * (668.72 * newCubic - 463.37 - 205.347 * newCubic.powi(2)) + 0.8192 * (668.72 * newCubic - 463.37 - 205.347 * newCubic.powi(2))) / (initialRefractiveIndex);
let attenuation = apparentAttenuation * 0.8192;
let abv = ((0.01 / 0.8192) * (initialRefractiveIndex - (0.18080000000000002 * initialRefractiveIndex + 0.8192 * (668.72 * newCubic - 463.37 - 205.347 * newCubic.powi(2)))) / (2.0665-0.010665 * initialRefractiveIndex)) * 100.0;
(abv, attenuation)
}
pub fn grainToABV(volumeInGallons: f32, weightInPounds: f32, grainGravity: f32) -> f32 {
pub fn grainToABV(volumeInGallons: f64, weightInPounds: f64, grainGravity: f64) -> f64 {
let extractPotential = grainGravity % 1.0 * 1000.0;
let extractionEfficiency = 0.57;
// sane default here of 57%
let mut originalGravity = 1.0;
// set to the gravity of water
let specificGravityPoints = (weightInPounds * extractPotential * extractionEfficiency) / volumeInGallons;
if specificGravityPoints == 0.0 {
let originalGravity = 1.0;
// set to the gravity of water
if specificGravityPoints != 0.0 {
originalGravity = specificGravityPoints / 1000.0 + 1.0;
originalGravity
} else {
let originalGravity = specificGravityPoints / 1000.0 + 1.0;
originalGravity
}
}
pub fn grainInfo(grainType: &String) -> f32 {
match grainType.as_ref() {
"2-Row PG" => 1.037,
"2-Row LVB" => 1.8,
"6-Row PG" => 1.035,
"6-Row LVB" => 1.8,
"Black PG" => 1.025,
"Black LVB" => 500.0,
"Caramel PG" => 1.034,
"Caramel 60 LVB" => 60.0,
"Caramel 80 LVB" => 80.0,
"Caramel 120 LVB" => 120.0,
"Chocolate PG" => 1.034,
"Chocolate LVB" => 350.0,
"Corn PG" => 1.037,
"Corn LVB" => 1.3,
"Dextrine PG" => 1.033,
"Dextrine LVB" => 1.5,
"Oat PG" => 1.034,
"Oat LVB" => 1.0,
"Rice PG" => 1.032,
"Rice LVB" => 1.0,
"Rye PG" => 1.036,
"Rye LVB" => 2.0,
"Wheat PG" => 1.036,
"Wheat LVB" => 1.6,
_ => 0.0,
pub fn grainInfo(grainType: &str) -> (f64, f64) {
match grainType {
// First value is Gravity, second value is Lovibond
"2-Row" => (1.037, 1.8),
"6-Row" => (1.035, 1.8),
"Black" => (1.025, 500.0),
"Caramel 60" => (1.034, 60.0),
"Caramel 80" => (1.034, 80.0),
"Caramel 120" => (1.033, 120.0),
"Chocolate" => (1.034, 350.0),
"Corn" => (1.037, 1.3),
"Dextrine" => (1.033, 1.5),
"Oat" => (1.034, 1.0),
"Rice" => (1.032, 1.0),
"Rye" => (1.036, 2.0),
"Wheat" => (1.036, 1.6),
_ => (1.0, 0.0),
// Gravity set to water, and color to nothing as a catch
}
}
pub fn glassSize(glassType: &str) -> f64 {
match glassType {
// Value is in centimeters
"Dimple Pint" => 9.8,
"Nonick Pint" => 9.0,
"Tulip Pint" => 8.5,
"Pilsner" => 8.0,
"Maß" => 10.5,
"Dimple Half Pint" => 8.0,
"Nonick Half Pint" => 7.0,
"Tulip Half Pint" => 7.2,
_ => 9.8,
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -2,31 +2,26 @@ use gtk;
use gtk::prelude::*;
use functions::commonFunctions::*;
pub fn guestimatePrep(ref guestimatorBuilderClone: &gtk::Builder) {
let guestimatorInput: &gtk::Entry = &guestimatorBuilderClone.get_object("guestimatorInput").unwrap();
pub fn guestimatePrep(guestimatorBuilderClone: &gtk::Builder) {
let guestimatorInput: gtk::Entry = guestimatorBuilderClone.get_object("guestimatorInput").unwrap();
let guestimatorInput = guestimatorInput.get_text().expect("No input");
let startingBrix = validInput(&guestimatorInput);
let guestimatorOutput = String::from("guestimatorOutput");
let guestimatorOutput: gtk::Entry = guestimatorBuilderClone.get_object("guestimatorOutput").unwrap();
if startingBrix == 0.0 {
let output: gtk::Entry = guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text("Enter a number");
guestimatorOutput.set_text("Enter a number");
} else if startingBrix < 2.57 {
guestimatorOutput.set_text("Enter a Brix greater than 2.57");
} else if startingBrix > 49.48 {
guestimatorOutput.set_text("Enter a Brix less than 49.48");
} else {
if startingBrix < 2.57 {
let output: gtk::Entry = guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text("Enter a number greater than 2.57");
} else if startingBrix > 49.48 {
let output: gtk::Entry = guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text("Enter a number less than 49.48");
} else {
guestiMaths(startingBrix, guestimatorOutput, &guestimatorBuilderClone);
}
guestiMaths(startingBrix, guestimatorBuilderClone);
}
}
fn guestiMaths(startingBrix: f32, guestimatorOutput: String, ref guestimatorBuilderClone: &gtk::Builder) {
let abv = format!("{:.2}%", guestimateABV(brixToGravity(startingBrix)));
let ref output: &gtk::Entry = &guestimatorBuilderClone.get_object(&guestimatorOutput).unwrap();
output.set_text(&abv.to_string());
fn guestiMaths(startingBrix: f64, guestimatorBuilderClone: &gtk::Builder) {
let guestimatorOutput: gtk::Entry = guestimatorBuilderClone.get_object("guestimatorOutput").unwrap();
let abv = format!("{:.2}%", realABV(startingBrix, finalBrixIdeal).0);
guestimatorOutput.set_text(&abv);
}
\ No newline at end of file
This diff is collapsed.
......@@ -2,74 +2,60 @@ use gtk;
use gtk::prelude::*;
use functions::commonFunctions::*;
pub fn gyleCarbonationPrep(ref gyleBuilderClone: &gtk::Builder) {
let gyleBrixInput: &gtk::Entry = &gyleBuilderClone.get_object("gyleBrixInput").unwrap();
pub fn gyleCarbonationPrep(gyleBuilderClone: &gtk::Builder) {
let gyleBrixInput: gtk::Entry = gyleBuilderClone.get_object("gyleBrixInput").unwrap();
let gyleBrixInputBuffer = gyleBrixInput.get_text().expect("No input");
let startingBrix = validInput(&gyleBrixInputBuffer);
let gyleCO2Input: &gtk::Entry = &gyleBuilderClone.get_object("gyleCO2Input").unwrap();
let gyleCO2Input: gtk::Entry = gyleBuilderClone.get_object("gyleCO2Input").unwrap();
let gyleCO2InputBuffer = gyleCO2Input.get_text().expect("No input");
let desiredCO2Level = validInput(&gyleCO2InputBuffer);
let gyleWortVolumeInput: &gtk::Entry = &gyleBuilderClone.get_object("gyleWortVolumeInput").unwrap();
let gyleWortVolumeInput: gtk::Entry = gyleBuilderClone.get_object("gyleWortVolumeInput").unwrap();
let gyleWortVolumeInputBuffer = gyleWortVolumeInput.get_text().expect("No input");
let finalVolume = validInput(&gyleWortVolumeInputBuffer);
let gyleOutput = String::from("gyleOutput");
let gyleOutput: &gtk::Entry = &gyleBuilderClone.get_object("gyleOutput").unwrap();
if startingBrix == 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&gyleOutput).unwrap();
output.set_text("Enter a number");
} else if desiredCO2Level == 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&gyleOutput).unwrap();
output.set_text("Enter a number");
} else if finalVolume == 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&gyleOutput).unwrap();
output.set_text("Enter a number");
if startingBrix < 2.57 {
gyleOutput.set_text("Enter a Starting Brix greater than 2.57");
} else if startingBrix > 49.48 {
gyleOutput.set_text("Enter a Starting Brix less than 49.48");
} else if startingBrix == 0.0 || desiredCO2Level == 0.0 || finalVolume == 0.0 {
gyleOutput.set_text("Enter all 3 inputs");
} else if startingBrix <= 0.0 || desiredCO2Level <= 0.0 || finalVolume <= 0.0 {
gyleOutput.set_text("Enter a positive number");
} else {
if startingBrix <= 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&gyleOutput).unwrap();
output.set_text("Enter a positive number");
} else if desiredCO2Level <= 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&gyleOutput).unwrap();
output.set_text("Enter a positive number");
} else if finalVolume <= 0.0 {
let output: gtk::Entry = gyleBuilderClone.get_object(&gyleOutput).unwrap();
output.set_text("Enter a positive number");
} else {
onGyleActivate(startingBrix, desiredCO2Level, finalVolume, &gyleBuilderClone);
}
onGyleActivate(startingBrix, desiredCO2Level, finalVolume, gyleBuilderClone);
}
}
fn onGyleActivate(startingBrix: f32, desiredCO2Level: f32, finalVolume: f32, ref gyleBuilderClone: &gtk::Builder) {
let ref gyleCarbonationSwitch: &gtk::Switch = &gyleBuilderClone.get_object("gyleCarbonationSwitch").unwrap();
fn onGyleActivate(startingBrix: f64, desiredCO2Level: f64, finalVolume: f64, gyleBuilderClone: &gtk::Builder) {
let gyleCarbonationSwitch: gtk::Switch = gyleBuilderClone.get_object("gyleCarbonationSwitch").unwrap();
if gyleCarbonationSwitch.get_active() == true {
let imperialOrMetric = String::from("metric");
gyleMaths(startingBrix, desiredCO2Level, finalVolume, imperialOrMetric, &gyleBuilderClone);
let imperialOrMetric = "metric";
gyleMaths(startingBrix, desiredCO2Level, finalVolume, imperialOrMetric, gyleBuilderClone);
} else if gyleCarbonationSwitch.get_active() == false {
let imperialOrMetric = String::from("imperial");
gyleMaths(startingBrix, desiredCO2Level, finalVolume, imperialOrMetric, &gyleBuilderClone);
let imperialOrMetric = "imperial";
gyleMaths(startingBrix, desiredCO2Level, finalVolume, imperialOrMetric, gyleBuilderClone);
}
}
fn gyleMaths(startingBrix: f32, desiredCO2Level: f32, finalVolume: f32, imperialOrMetric: String, ref gyleBuilderClone: &gtk::Builder) {
fn gyleMaths(startingBrix: f64, desiredCO2Level: f64, finalVolume: f64, imperialOrMetric: &str, gyleBuilderClone: &gtk::Builder) {
let startingGravity = brixToGravity(startingBrix);
let finalGravity: f32 = 1.015;
let startingPlato = gravityToPlato(startingGravity);
let finalPlato = gravityToPlato(finalGravity);
let finalPlato = gravityToPlato(finalGravityIdeal);
let ref gyleOutput: &gtk::Entry = &gyleBuilderClone.get_object("gyleOutput").unwrap();
let gyleOutput: &gtk::Entry = &gyleBuilderClone.get_object("gyleOutput").unwrap();
if imperialOrMetric == "imperial" {
let gyleVolume = ((0.24 * finalVolume * 3.7854 * desiredCO2Level) / (startingPlato - finalPlato)) * 0.2641729;
let total = format!("{:.2} gallons", &gyleVolume);
let gyleVolume = litresToGallons((0.24 * gallonsToLitres(finalVolume) * desiredCO2Level) / (startingPlato - finalPlato));
let total = format!("{:.2} gallons", gyleVolume);
gyleOutput.set_text(&total);
} else if imperialOrMetric == "metric" {
let gyleVolume = (0.24 * finalVolume * desiredCO2Level) / (startingPlato - finalPlato);
let total = format!("{:.2} litres", &gyleVolume);
let total = format!("{:.2} litres", gyleVolume);
gyleOutput.set_text(&total);
}
}
\ No newline at end of file
......@@ -2,77 +2,71 @@ use gtk;
use gtk::prelude::*;
use functions::commonFunctions::*;
pub fn increaseABVPrep(ref increaseABVBuilderClone: &gtk::Builder) {
let increaseABVBrixInput: &gtk::Entry = &increaseABVBuilderClone.get_object("increaseABVBrixInput").unwrap();
pub fn increaseABVPrep(increaseABVBuilderClone: &gtk::Builder) {
let increaseABVBrixInput: gtk::Entry = increaseABVBuilderClone.get_object("increaseABVBrixInput").unwrap();
let increaseABVBrixInputBuffer = increaseABVBrixInput.get_text().expect("No input");
let startingBrix = validInput(&increaseABVBrixInputBuffer);
let increaseABVABVInput: &gtk::Entry = &increaseABVBuilderClone.get_object("increaseABVABVInput").unwrap();
let increaseABVABVInput: gtk::Entry = increaseABVBuilderClone.get_object("increaseABVABVInput").unwrap();
let increaseABVABVInputBuffer = increaseABVABVInput.get_text().expect("No input");
let desiredABV = validInput(&increaseABVABVInputBuffer);
let increaseABVVolumeInput: &gtk::Entry = &increaseABVBuilderClone.get_object("increaseABVVolumeInput").unwrap();
let increaseABVVolumeInput: gtk::Entry = increaseABVBuilderClone.get_object("increaseABVVolumeInput").unwrap();
let increaseABVVolumeInputBuffer = increaseABVVolumeInput.get_text().expect("No input");
let desiredWortVolume = validInput(&increaseABVVolumeInputBuffer);
let increaseABVNewBrixOutput = String::from("increaseABVNewBrixOutput");
let increaseABVNewBrixOutput: gtk::Entry = increaseABVBuilderClone.get_object("increaseABVNewBrixOutput").unwrap();
let increaseABVSugarAddOutput: gtk::Entry = increaseABVBuilderClone.get_object("increaseABVSugarAddOutput").unwrap();
let increaseABVHoneyAddOutput: gtk::Entry = increaseABVBuilderClone.get_object("increaseABVHoneyAddOutput").unwrap();
if startingBrix == 0.0 {
let output: gtk::Entry = increaseABVBuilderClone.get_object(&increaseABVNewBrixOutput).unwrap();
output.set_text("Enter a number");
} else if desiredABV == 0.0 {
let output: gtk::Entry = increaseABVBuilderClone.get_object(&increaseABVNewBrixOutput).unwrap();
output.set_text("Enter a number");
} else if desiredWortVolume == 0.0 {
let output: gtk::Entry = increaseABVBuilderClone.get_object(&increaseABVNewBrixOutput).unwrap();
output.set_text("Enter a number");
if startingBrix < 2.57 {
increaseABVNewBrixOutput.set_text("Enter a brix greater than 2.57");
increaseABVSugarAddOutput.set_text("");
increaseABVHoneyAddOutput.set_text("");
} else if startingBrix > 49.48 {
increaseABVNewBrixOutput.set_text("Enter a brix less than 49.48");
increaseABVSugarAddOutput.set_text("");
increaseABVHoneyAddOutput.set_text("");
} else if startingBrix == 0.0 || desiredABV == 0.0 || desiredWortVolume == 0.0 {
increaseABVNewBrixOutput.set_text("Enter all 3 inputs");
increaseABVSugarAddOutput.set_text("");
increaseABVHoneyAddOutput.set_text("");
} else if desiredABV <= 0.0 || desiredWortVolume <= 0.0 {
increaseABVNewBrixOutput.set_text("Enter a positive number");
increaseABVSugarAddOutput.set_text("");
increaseABVHoneyAddOutput.set_text("");
} else {
if startingBrix <= 0.0 {
let output: gtk::Entry = increaseABVBuilderClone.get_object(&increaseABVNewBrixOutput).unwrap();
output.set_text("Enter a positive number");
} else if desiredABV <= 0.0 {
let output: gtk::Entry = increaseABVBuilderClone.get_object(&increaseABVNewBrixOutput).unwrap();
output.set_text("Enter a positive number");
} else if desiredWortVolume <= 0.0 {
let output: gtk::Entry = increaseABVBuilderClone.get_object(&increaseABVNewBrixOutput).unwrap();
output.set_text("Enter a positive number");
} else {
onIncreaseActivate(startingBrix, desiredABV, desiredWortVolume, &increaseABVBuilderClone);
}
onIncreaseActivate(startingBrix, desiredABV, desiredWortVolume, increaseABVBuilderClone);
}
}
fn onIncreaseActivate(startingBrix: f32, desiredABV: f32, desiredWortVolume: f32, ref increaseABVBuilderClone: &gtk::Builder) {
let ref increaseABVSwitch: &gtk::Switch = &increaseABVBuilderClone.get_object("increaseABVSwitch").unwrap();
fn onIncreaseActivate(startingBrix: f64, desiredABV: f64, desiredWortVolume: f64, increaseABVBuilderClone: &gtk::Builder) {
let increaseABVSwitch: &gtk::Switch = &increaseABVBuilderClone.get_object("increaseABVSwitch").unwrap();
if increaseABVSwitch.get_active() == true {
let imperialOrMetric = String::from("metric");