diff options
| author | sam-anthony <samanthony6@protonmail.com> | 2022-03-26 13:35:58 -0230 |
|---|---|---|
| committer | sam-anthony <samanthony6@protonmail.com> | 2022-03-26 13:35:58 -0230 |
| commit | e8c878f4236c056b1c0c9308e2d49c5b23833963 (patch) | |
| tree | 01f53ee620e256fa7b87ea43656b9315735e9c2a | |
| parent | 90f42ad66feb6b77474d0da267d572eca16e2826 (diff) | |
| download | volute-e8c878f4236c056b1c0c9308e2d49c5b23833963.zip | |
pressure and rough layout
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Cargo.lock | 323 | ||||
| -rw-r--r-- | Cargo.toml | 10 | ||||
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | go.mod | 18 | ||||
| -rw-r--r-- | go.sum | 37 | ||||
| -rw-r--r-- | main.go | 66 | ||||
| -rw-r--r-- | pressure.go | 54 | ||||
| -rw-r--r-- | src/app.rs | 84 | ||||
| -rw-r--r-- | src/input.rs | 97 | ||||
| -rw-r--r-- | src/lib.rs | 4 | ||||
| -rw-r--r-- | src/main.rs | 113 | ||||
| -rw-r--r-- | src/ui.rs | 43 | ||||
| -rw-r--r-- | src/unit_of_measurement.rs | 54 |
14 files changed, 186 insertions, 729 deletions
@@ -1 +1 @@ -/target +/volute diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index ae9b203..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,323 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "crossterm" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85525306c4291d1b73ce93c8acf9c339f9b213aef6c1d85c3830cbf1c16325c" -dependencies = [ - "bitflags", - "crossterm_winapi", - "libc", - "mio", - "parking_lot 0.11.2", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b75a27dc8d220f1f8521ea69cd55a34d720a200ebb3a624d9aa19193d3b432" -dependencies = [ - "bitflags", - "crossterm_winapi", - "libc", - "mio", - "parking_lot 0.12.0", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" -dependencies = [ - "winapi", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "libc" -version = "0.2.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" - -[[package]] -name = "lock_api" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "mio" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.5", -] - -[[package]] -name = "parking_lot" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.1", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "signal-hook" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "tui" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ed0a32c88b039b73f1b6c5acbd0554bfa5b6be94467375fd947c4de3a02271" -dependencies = [ - "bitflags", - "cassowary", - "crossterm 0.22.1", - "unicode-segmentation", - "unicode-width", -] - -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "volute" -version = "0.1.0" -dependencies = [ - "crossterm 0.23.0", - "tui", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" - -[[package]] -name = "windows_i686_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" - -[[package]] -name = "windows_i686_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index f5ba083..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "volute" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -crossterm = "0.23" -tui = "0.17" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d92c5fa --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +build: tidy format + go build +run: tidy format + go run . + +format: + gofmt -s -w . + +tidy: + go mod tidy @@ -0,0 +1,18 @@ +module github.com/sam-anthony/volute + +go 1.18 + +require github.com/AllenDang/giu v0.6.2 + +require ( + github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 // indirect + github.com/AllenDang/imgui-go v1.12.1-0.20220322114136-499bbf6a42ad // indirect + github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 // indirect + github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220320163800-277f93cfa958 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/sahilm/fuzzy v0.1.0 // indirect + golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect + golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect + gopkg.in/eapache/queue.v1 v1.1.0 // indirect +) @@ -0,0 +1,37 @@ +github.com/AllenDang/giu v0.6.2 h1:CFIHSQxDqEFNsNnTO9LXBVZ8zlInV71H3M6V3BNagmI= +github.com/AllenDang/giu v0.6.2/go.mod h1:9hCQh0l0wbBzOqe9cr02EB9EsNOy9AwFIjG4xVsR6TI= +github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= +github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= +github.com/AllenDang/imgui-go v1.12.1-0.20220322114136-499bbf6a42ad h1:Kr961C2uEEAklK+jBRiZVnQH0AgS7o6pXrIgUTUUGiM= +github.com/AllenDang/imgui-go v1.12.1-0.20220322114136-499bbf6a42ad/go.mod h1:kuPs9RWleaUuK7D49bE6HPxyRA36Lp4ICKGp+5OnnbY= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= +github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M= +github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk= +github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220320163800-277f93cfa958 h1:TL70PMkdPCt9cRhKTqsm+giRpgrd0IGEj763nNr2VFY= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220320163800-277f93cfa958/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= +github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/eapache/queue.v1 v1.1.0 h1:EldqoJEGtXYiVCMRo2C9mePO2UUGnYn2+qLmlQSqPdc= +gopkg.in/eapache/queue.v1 v1.1.0/go.mod h1:wNtmx1/O7kZSR9zNT1TTOJ7GLpm3Vn7srzlfylFbQwU= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -0,0 +1,66 @@ +package main + +import ( + "fmt" + g "github.com/AllenDang/giu" + "os" +) + +func check(err error) { + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +var ( + manifoldPressure pressure + + // selectedPressureUnit is used to index pressureUnits + selectedPressureUnit int32 +) + +func init() { + manifoldPressure = pressure{100, defaultPressureUnit} + + // selectedPressureUnit is used to index pressureUnitStrings + selectedPressureUnit = defaultPressureUnitIndex +} + +func loop() { + g.SingleWindow().Layout( + g.Table(). + Rows( + g.TableRow( + g.Label("Manifold Absolute Pressure"), + g.Combo( + "", + pressureUnitStrings()[selectedPressureUnit], + pressureUnitStrings(), + &selectedPressureUnit, + ). + OnChange(func() { + s := pressureUnitStrings()[selectedPressureUnit] + u, err := pressureUnitFromString(s) + check(err) + + manifoldPressure = pressure{ + manifoldPressure.asUnit(u), + u, + } + }), + g.InputFloat(&manifoldPressure.val).Format("%.2f"), + ), + ). + Columns( + g.TableColumn("Parameter"), + g.TableColumn("Unit"), + g.TableColumn("Point 1"), + ), + ) +} + +func main() { + wnd := g.NewMasterWindow("volute", 400, 200, 0) + wnd.Run(loop) +} diff --git a/pressure.go b/pressure.go new file mode 100644 index 0000000..f486552 --- /dev/null +++ b/pressure.go @@ -0,0 +1,54 @@ +package main + +import ( + "errors" + "fmt" +) + +type pressureUnit float32 + +const ( + pascal pressureUnit = 1 + kilopascal pressureUnit = 1_000 + bar pressureUnit = 100_000 + poundsPerSquareInch pressureUnit = 6_894.757 +) + +// pressureUnitStrings returns a slice of strings, each representing a +// pressureUnit. +// This is necessary because giu.Combo only works with strings. +func pressureUnitStrings() []string { + return []string{"Pa", "kPa", "bar", "psi"} +} + +const ( + defaultPressureUnit pressureUnit = kilopascal + // Used to index pressureUnitStrings + defaultPressureUnitIndex int32 = 1 // kPa +) + +func pressureUnitFromString(s string) (pressureUnit, error) { + // Each case corresponds to a value in pressureUnitStrings + switch s { + case "Pa": + return pascal, nil + case "kPa": + return kilopascal, nil + case "bar": + return bar, nil + case "psi": + return poundsPerSquareInch, nil + default: + return *new(pressureUnit), errors.New(fmt.Sprintf("invalid pressureUnit: '%s'", s)) + } +} + +type pressure struct { + val float32 + unit pressureUnit +} + +func (p pressure) asUnit(u pressureUnit) float32 { + pa := p.val * float32(p.unit) // Convert to pascals. + return pa / float32(u) // Convert to desired unit. +} diff --git a/src/app.rs b/src/app.rs deleted file mode 100644 index 1ca6196..0000000 --- a/src/app.rs +++ /dev/null @@ -1,84 +0,0 @@ -use crate::{ - input::{InputParam, Row}, - unit_of_measurement::pressure, -}; - -pub struct App { - rows: Vec<Row>, - selected_row: usize, - selected_column: InputParam, - - pub pressure_unit: pressure::Unit, -} - -impl App { - pub fn rows(&self) -> &Vec<Row> { - &self.rows - } - - pub fn next_row(&mut self) { - if self.selected_row < self.rows.len() - 1 { - self.selected_row += 1; - } else { - self.selected_row = 0; - } - } - - pub fn previous_row(&mut self) { - if self.selected_row > 0 { - self.selected_row -= 1; - } else { - self.selected_row = self.rows.len() - 1; - } - } - - pub fn next_column(&mut self) { - self.selected_column = self.selected_column.next(); - } - - pub fn previous_column(&mut self) { - self.selected_column = self.selected_column.previous(); - } - - pub fn insert_row(&mut self) { - let index = self.selected_row; - self.rows.insert(index, self.rows[index].clone()); - } - - pub fn remove_row(&mut self) { - if self.rows.len() > 1 { - self.rows.remove(self.selected_row); - // If we remove the last row, the selected row will be out of range. - if self.selected_row >= self.rows.len() { - self.selected_row = self.rows.len() - 1; - } - } - } - - pub fn selected_input_param(&self) -> &InputParam { - match self.selected_column { - InputParam::Rpm(_) => &self.rows[self.selected_row].rpm, - InputParam::Ve(_) => &self.rows[self.selected_row].ve, - InputParam::Map(_) => &self.rows[self.selected_row].map, - } - } - - pub fn selected_input_param_mut(&mut self) -> &mut InputParam { - match self.selected_column { - InputParam::Rpm(_) => &mut self.rows[self.selected_row].rpm, - InputParam::Ve(_) => &mut self.rows[self.selected_row].ve, - InputParam::Map(_) => &mut self.rows[self.selected_row].map, - } - } -} - -impl Default for App { - fn default() -> App { - App { - rows: vec![Row::default()], - selected_row: 0, - selected_column: InputParam::Rpm(0), - pressure_unit: pressure::Unit::KiloPascal, - } - } -} diff --git a/src/input.rs b/src/input.rs deleted file mode 100644 index 00cf410..0000000 --- a/src/input.rs +++ /dev/null @@ -1,97 +0,0 @@ -use crate::unit_of_measurement::{ - pressure::{Pressure, Unit::KiloPascal}, - UnitOfMeasurement, -}; - -// A row in the inputs table has one of each variation. -#[derive(Clone)] -pub enum InputParam { - Rpm(u32), // Revolutions per minute - Ve(u32), // Volumetric efficiency - Map(Pressure), // Manifold absolute pressure -} - -impl InputParam { - /* next() and previous() allow InputParam to act as a circular iterator of - * sorts. next() will return the next variation as they are defined. When - * it reaches the end, the first variation will be returned: - * RPM->VE->MAP->RPM->etc... - * previous() simply goes the opposite direction: - * MAP->VE->RPM->MAP->etc... - */ - pub fn next(&self) -> Self { - match self { - Self::Rpm(_) => Self::Ve(0), - Self::Ve(_) => Self::Map(Pressure::default()), - Self::Map(_) => Self::Rpm(0), - } - } - - pub fn previous(&self) -> Self { - match self { - Self::Rpm(_) => Self::Map(Pressure::default()), - Self::Ve(_) => Self::Rpm(0), - Self::Map(_) => Self::Ve(0), - } - } -} - -// A row in the inputs table. Contains one of each variation of InputParam. -#[derive(Clone)] -pub struct Row { - pub rpm: InputParam, - pub ve: InputParam, - pub map: InputParam, -} - -impl Row { - pub fn iter(&self) -> RowIter { - RowIter::from_row(&self) - } -} - -impl Default for Row { - fn default() -> Self { - Self { - rpm: InputParam::Rpm(7000), - ve: InputParam::Ve(95), - map: InputParam::Map(Pressure::from_unit(KiloPascal, 200)), - } - } -} - -pub struct RowIter<'a> { - row: &'a Row, - iter_state: Option<InputParam>, -} - -impl<'a> RowIter<'a> { - fn from_row(row: &'a Row) -> Self { - Self { - row: row, - iter_state: Some(InputParam::Rpm(0)), - } - } -} - -impl<'a> Iterator for RowIter<'a> { - type Item = &'a InputParam; - - fn next(&mut self) -> Option<Self::Item> { - match self.iter_state { - Some(InputParam::Rpm(_)) => { - self.iter_state = Some(InputParam::Ve(0)); - Some(&self.row.rpm) - } - Some(InputParam::Ve(_)) => { - self.iter_state = Some(InputParam::Map(Pressure::default())); - Some(&self.row.ve) - } - Some(InputParam::Map(_)) => { - self.iter_state = None; - Some(&self.row.map) - } - None => None, - } - } -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index b33113b..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod app; -pub mod input; -pub mod ui; -pub mod unit_of_measurement; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 60b1fed..0000000 --- a/src/main.rs +++ /dev/null @@ -1,113 +0,0 @@ -use crossterm::{ - event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, - execute, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, -}; -use std::{error::Error, io}; -use tui::{ - backend::{Backend, CrosstermBackend}, - layout::{Constraint, Direction, Layout}, - Frame, Terminal, -}; -use volute::{ - app::App, - input::InputParam, - ui, - unit_of_measurement::{pressure::Pressure, UnitOfMeasurement}, -}; - -fn main() -> Result<(), Box<dyn Error>> { - // setup terminal - enable_raw_mode()?; - let mut stdout = io::stdout(); - execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; - let backend = CrosstermBackend::new(stdout); - let mut terminal = Terminal::new(backend)?; - - // create app and run it - let app = App::default(); - let res = run_app(&mut terminal, app); - - // restore terminal - disable_raw_mode()?; - execute!( - terminal.backend_mut(), - LeaveAlternateScreen, - DisableMouseCapture - )?; - terminal.show_cursor()?; - - if let Err(err) = res { - println!("{:?}", err) - } - - Ok(()) -} - -// Input handling -fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<()> { - loop { - terminal.draw(|f| ui(f, &app))?; - - if let Event::Key(key) = event::read()? { - match key.code { - KeyCode::Char('q') => { - return Ok(()); - } - KeyCode::Char('j') => app.next_row(), - KeyCode::Char('k') => app.previous_row(), - KeyCode::Char('l') => app.next_column(), - KeyCode::Char('h') => app.previous_column(), - KeyCode::Char('y') => app.insert_row(), - KeyCode::Char('d') => app.remove_row(), - KeyCode::Char('p') => app.pressure_unit.next(), - KeyCode::Char(c) => { - if ('0'..':').contains(&c) { - // 0 to 9 inclusive - let digit = c.to_digit(10).unwrap(); - match app.selected_input_param() { - InputParam::Rpm(rpm) => { - *app.selected_input_param_mut() = - InputParam::Rpm(*rpm * 10 + digit); - } - InputParam::Ve(ve) => { - *app.selected_input_param_mut() = InputParam::Ve(*ve * 10 + digit); - } - InputParam::Map(p) => { - *app.selected_input_param_mut() = - InputParam::Map(Pressure::from_unit( - app.pressure_unit, - p.as_unit(app.pressure_unit) * 10 + digit as i32, - )) - } - } - } - } - KeyCode::Backspace => match app.selected_input_param() { - InputParam::Rpm(rpm) => { - *app.selected_input_param_mut() = InputParam::Rpm(*rpm / 10); - } - InputParam::Ve(ve) => { - *app.selected_input_param_mut() = InputParam::Ve(*ve / 10); - } - InputParam::Map(p) => { - *app.selected_input_param_mut() = InputParam::Map(Pressure::from_unit( - app.pressure_unit, - p.as_unit(app.pressure_unit) / 10, - )) - } - }, - _ => {} - } - } - } -} - -fn ui<B: Backend>(f: &mut Frame<B>, app: &App) { - let layout = Layout::default() - .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) - .split(f.size()); - f.render_widget(ui::input_table(app), layout[0]); - f.render_widget(ui::output_table(app), layout[1]); -} diff --git a/src/ui.rs b/src/ui.rs deleted file mode 100644 index 65b1ad0..0000000 --- a/src/ui.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::{app::App, input::InputParam, unit_of_measurement::UnitOfMeasurement}; -use std::ptr; -use tui::{ - layout::Constraint, - style::{Color, Style}, - widgets::{self, Block, Borders, Cell, Paragraph, Table, Widget}, -}; - -pub fn input_table(app: &App) -> impl Widget { - let rows = app.rows().iter().map(|row| { - let cells = row.iter().map(|item| { - let item_str = match item { - InputParam::Rpm(rpm) => rpm.to_string(), - InputParam::Ve(ve) => ve.to_string(), - InputParam::Map(p) => p.as_unit(app.pressure_unit).to_string(), - }; - if ptr::eq(item, app.selected_input_param()) { - Cell::from(item_str).style(Style::default().fg(Color::Yellow)) - } else { - Cell::from(item_str) - } - }); - widgets::Row::new(cells) - }); - - Table::new(rows) - .header(widgets::Row::new(vec!["rpm", "ve", "map"])) - .block(Block::default().borders(Borders::ALL).title("inputs")) - .widths(&[ - Constraint::Length(5), // rpm - Constraint::Length(3), // ve - Constraint::Length(3), // map - ]) -} - -pub fn output_table(app: &App) -> impl Widget { - if let InputParam::Map(p) = &app.rows()[0].map { - Paragraph::new(p.as_unit(app.pressure_unit).to_string()) - .block(Block::default().title("map").borders(Borders::ALL)) - } else { - Paragraph::new("err").block(Block::default().title("map").borders(Borders::ALL)) - } -} diff --git a/src/unit_of_measurement.rs b/src/unit_of_measurement.rs deleted file mode 100644 index ce459bf..0000000 --- a/src/unit_of_measurement.rs +++ /dev/null @@ -1,54 +0,0 @@ -pub trait UnitOfMeasurement { - type Unit; - - fn from_unit(unit: Self::Unit, n: i32) -> Self; - fn as_unit(&self, unit: Self::Unit) -> i32; -} - -pub mod pressure { - use super::UnitOfMeasurement; - - #[derive(Default, Clone)] - pub struct Pressure(i32); - - #[derive(Copy, Clone)] - pub enum Unit { - Pascal = 1, - KiloPascal = 1000, - } - - impl Unit { - // Pseudo iter::Cycle behavior. - pub fn next(&mut self) { - match self { - Unit::Pascal => { - *self = Unit::KiloPascal; - } - Unit::KiloPascal => { - *self = Unit::Pascal; - } - } - } - } - - impl ToString for Unit { - fn to_string(&self) -> String { - match self { - Self::Pascal => String::from("Pa"), - Self::KiloPascal => String::from("kPa"), - } - } - } - - impl UnitOfMeasurement for Pressure { - type Unit = Unit; - - fn from_unit(unit: Self::Unit, n: i32) -> Self { - Self(n * unit as i32) - } - - fn as_unit(&self, unit: Self::Unit) -> i32 { - self.0 / unit as i32 - } - } -} |