calculator.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. This example is a simple iOS-style calculator. This particular example can run any platform - Web, Mobile, Desktop.
  3. This calculator version uses React-style state management. All state is held as individual use_states.
  4. */
  5. use dioxus::events::*;
  6. use dioxus::html::input_data::keyboard_types::Key;
  7. use dioxus::prelude::*;
  8. use dioxus_desktop::{Config, LogicalSize, WindowBuilder};
  9. fn main() {
  10. let config = Config::new().with_window(
  11. WindowBuilder::default()
  12. .with_title("Calculator")
  13. .with_inner_size(LogicalSize::new(300.0, 525.0)),
  14. );
  15. LaunchBuilder::desktop().with_cfg(config).launch(app);
  16. }
  17. fn app() -> Element {
  18. let mut val = use_signal(|| String::from("0"));
  19. let mut input_digit = move |num: u8| {
  20. if val.cloned() == "0" {
  21. val.set(String::new());
  22. }
  23. val.write().push_str(num.to_string().as_str());
  24. };
  25. let mut input_operator = move |key: &str| val.write().push_str(key);
  26. let mut handle_key_down_event = move |evt: KeyboardEvent| match evt.key() {
  27. Key::Backspace => {
  28. if !val.cloned().is_empty() {
  29. val.write().pop();
  30. }
  31. }
  32. Key::Character(character) => match character.as_str() {
  33. "+" => input_operator("+"),
  34. "-" => input_operator("-"),
  35. "/" => input_operator("/"),
  36. "*" => input_operator("*"),
  37. "0" => input_digit(0),
  38. "1" => input_digit(1),
  39. "2" => input_digit(2),
  40. "3" => input_digit(3),
  41. "4" => input_digit(4),
  42. "5" => input_digit(5),
  43. "6" => input_digit(6),
  44. "7" => input_digit(7),
  45. "8" => input_digit(8),
  46. "9" => input_digit(9),
  47. _ => {}
  48. },
  49. _ => {}
  50. };
  51. rsx! {
  52. style { {include_str!("./assets/calculator.css")} }
  53. div { id: "wrapper",
  54. div { class: "app",
  55. div { class: "calculator", tabindex: "0", onkeydown: handle_key_down_event,
  56. div { class: "calculator-display", "{val}" }
  57. div { class: "calculator-keypad",
  58. div { class: "input-keys",
  59. div { class: "function-keys",
  60. button {
  61. class: "calculator-key key-clear",
  62. onclick: move |_| {
  63. val.set(String::new());
  64. if !val.cloned().is_empty() {
  65. val.set("0".into());
  66. }
  67. },
  68. if val.cloned().is_empty() { "C" } else { "AC" }
  69. }
  70. button {
  71. class: "calculator-key key-sign",
  72. onclick: move |_| {
  73. let temp = calc_val(val.cloned().as_str());
  74. if temp > 0.0 {
  75. val.set(format!("-{temp}"));
  76. } else {
  77. val.set(format!("{}", temp.abs()));
  78. }
  79. },
  80. "±"
  81. }
  82. button {
  83. class: "calculator-key key-percent",
  84. onclick: move |_| {
  85. val.set(format!("{}", calc_val(val.cloned().as_str()) / 100.0));
  86. },
  87. "%"
  88. }
  89. }
  90. div { class: "digit-keys",
  91. button {
  92. class: "calculator-key key-0",
  93. onclick: move |_| input_digit(0),
  94. "0"
  95. }
  96. button {
  97. class: "calculator-key key-dot",
  98. onclick: move |_| val.write().push('.'),
  99. "●"
  100. }
  101. for k in 1..10 {
  102. button {
  103. class: "calculator-key {k}",
  104. name: "key-{k}",
  105. onclick: move |_| input_digit(k),
  106. "{k}"
  107. }
  108. }
  109. }
  110. }
  111. div { class: "operator-keys",
  112. button {
  113. class: "calculator-key key-divide",
  114. onclick: move |_| input_operator("/"),
  115. "÷"
  116. }
  117. button {
  118. class: "calculator-key key-multiply",
  119. onclick: move |_| input_operator("*"),
  120. "×"
  121. }
  122. button {
  123. class: "calculator-key key-subtract",
  124. onclick: move |_| input_operator("-"),
  125. "−"
  126. }
  127. button {
  128. class: "calculator-key key-add",
  129. onclick: move |_| input_operator("+"),
  130. "+"
  131. }
  132. button {
  133. class: "calculator-key key-equals",
  134. onclick: move |_| val.set(format!("{}", calc_val(val.cloned().as_str()))),
  135. "="
  136. }
  137. }
  138. }
  139. }
  140. }
  141. }
  142. }
  143. }
  144. fn calc_val(val: &str) -> f64 {
  145. let mut temp = String::new();
  146. let mut operation = "+".to_string();
  147. let mut start_index = 0;
  148. let mut temp_value;
  149. let mut fin_index = 0;
  150. if &val[0..1] == "-" {
  151. temp_value = String::from("-");
  152. fin_index = 1;
  153. start_index += 1;
  154. } else {
  155. temp_value = String::from("");
  156. }
  157. for c in val[fin_index..].chars() {
  158. if c == '+' || c == '-' || c == '*' || c == '/' {
  159. break;
  160. }
  161. temp_value.push(c);
  162. start_index += 1;
  163. }
  164. let mut result = temp_value.parse::<f64>().unwrap();
  165. if start_index + 1 >= val.len() {
  166. return result;
  167. }
  168. for c in val[start_index..].chars() {
  169. if c == '+' || c == '-' || c == '*' || c == '/' {
  170. if !temp.is_empty() {
  171. match &operation as &str {
  172. "+" => result += temp.parse::<f64>().unwrap(),
  173. "-" => result -= temp.parse::<f64>().unwrap(),
  174. "*" => result *= temp.parse::<f64>().unwrap(),
  175. "/" => result /= temp.parse::<f64>().unwrap(),
  176. _ => unreachable!(),
  177. };
  178. }
  179. operation = c.to_string();
  180. temp = String::new();
  181. } else {
  182. temp.push(c);
  183. }
  184. }
  185. if !temp.is_empty() {
  186. match &operation as &str {
  187. "+" => result += temp.parse::<f64>().unwrap(),
  188. "-" => result -= temp.parse::<f64>().unwrap(),
  189. "*" => result *= temp.parse::<f64>().unwrap(),
  190. "/" => result /= temp.parse::<f64>().unwrap(),
  191. _ => unreachable!(),
  192. };
  193. }
  194. result
  195. }