Basic Calc functions
This commit is contained in:
219
src/ui.rs
Normal file
219
src/ui.rs
Normal file
@@ -0,0 +1,219 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
/// The main calculator component.
|
||||
/// We use `allow(non_snake_case)` because Dioxus components are typically CamelCase.
|
||||
#[allow(non_snake_case)]
|
||||
#[component]
|
||||
pub fn Calculator() -> Element {
|
||||
// --- State Management ---
|
||||
// `first_num`: Stores the first number entered.
|
||||
// `second_num`: Stores the second number entered.
|
||||
// `operator`: Stores the current operator (+, -, *, /).
|
||||
let mut first_num = use_signal(String::new);
|
||||
let mut second_num = use_signal(String::new);
|
||||
let mut operator = use_signal(String::new);
|
||||
|
||||
rsx! {
|
||||
// Main container for the calculator
|
||||
div { class: "app-container",
|
||||
div { class: "calculator-wrap",
|
||||
// Display Screen
|
||||
div { class: "display-area",
|
||||
div { class: "display-text",
|
||||
// Logic: If first number is empty, show "0"
|
||||
if first_num().is_empty() {
|
||||
"0"
|
||||
} else {
|
||||
"{first_num}"
|
||||
}
|
||||
" "
|
||||
span { class: "operator-symbol", "{operator}" }
|
||||
" "
|
||||
"{second_num}"
|
||||
}
|
||||
}
|
||||
|
||||
// Button Grid
|
||||
div { class: "keypad-grid",
|
||||
// --- Row 1 ---
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "7"),
|
||||
"7"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "8"),
|
||||
"8"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "9"),
|
||||
"9"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-operator",
|
||||
onclick: move |_| handle_operator(first_num, second_num, operator, "/"),
|
||||
"/"
|
||||
}
|
||||
|
||||
// --- Row 2 ---
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "4"),
|
||||
"4"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "5"),
|
||||
"5"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "6"),
|
||||
"6"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-operator",
|
||||
onclick: move |_| handle_operator(first_num, second_num, operator, "*"),
|
||||
"*"
|
||||
}
|
||||
|
||||
// --- Row 3 ---
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "1"),
|
||||
"1"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "2"),
|
||||
"2"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-number",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "3"),
|
||||
"3"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-operator",
|
||||
onclick: move |_| handle_operator(first_num, second_num, operator, "-"),
|
||||
"-"
|
||||
}
|
||||
|
||||
// --- Row 4 ---
|
||||
button {
|
||||
class: "calc-btn btn-number btn-zero",
|
||||
onclick: move |_| input_digit(first_num, second_num, operator, "0"),
|
||||
"0"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-clear",
|
||||
onclick: move |_| {
|
||||
first_num.set(String::new());
|
||||
second_num.set(String::new());
|
||||
operator.set(String::new());
|
||||
},
|
||||
"C"
|
||||
}
|
||||
button {
|
||||
class: "calc-btn btn-operator",
|
||||
onclick: move |_| handle_operator(first_num, second_num, operator, "+"),
|
||||
"+"
|
||||
}
|
||||
|
||||
// --- Row 5 (Equals) ---
|
||||
button {
|
||||
class: "calc-btn btn-equals",
|
||||
onclick: move |_| calculate_result(first_num, second_num, operator),
|
||||
"="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to add a digit to the current number
|
||||
fn input_digit(
|
||||
mut first_num: Signal<String>,
|
||||
mut second_num: Signal<String>,
|
||||
operator: Signal<String>,
|
||||
digit: &str,
|
||||
) {
|
||||
if operator().is_empty() {
|
||||
first_num.write().push_str(digit);
|
||||
} else {
|
||||
second_num.write().push_str(digit);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper logic for operators
|
||||
fn handle_operator(
|
||||
first_num: Signal<String>,
|
||||
second_num: Signal<String>,
|
||||
mut operator: Signal<String>,
|
||||
op: &str,
|
||||
) {
|
||||
if !first_num().is_empty() && second_num().is_empty() {
|
||||
operator.set(op.to_string());
|
||||
} else if !second_num().is_empty() {
|
||||
// If we already have two numbers, calculate first, then set new operator
|
||||
calculate_result(first_num, second_num, operator);
|
||||
operator.set(op.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs the calculation based on current state
|
||||
fn calculate_result(
|
||||
mut first_num: Signal<String>,
|
||||
mut second_num: Signal<String>,
|
||||
mut operator: Signal<String>,
|
||||
) {
|
||||
// Parse numbers
|
||||
let num1_str = first_num();
|
||||
let num2_str = second_num();
|
||||
let op = operator();
|
||||
|
||||
// If we don't have a second number, we can't calculate
|
||||
if num2_str.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to parse strings to floats
|
||||
let n1 = match num1_str.parse::<f64>() {
|
||||
Ok(n) => n,
|
||||
Err(_) => return, // Invalid number
|
||||
};
|
||||
|
||||
let n2 = match num2_str.parse::<f64>() {
|
||||
Ok(n) => n,
|
||||
Err(_) => return, // Invalid number
|
||||
};
|
||||
|
||||
// Calculate result
|
||||
let result = match op.as_str() {
|
||||
"+" => (n1 + n2).to_string(),
|
||||
"-" => (n1 - n2).to_string(),
|
||||
"*" => (n1 * n2).to_string(),
|
||||
"/" => {
|
||||
if n2 == 0.0 {
|
||||
"Error".to_string()
|
||||
} else {
|
||||
(n1 / n2).to_string()
|
||||
}
|
||||
}
|
||||
_ => return, // Unknown operator
|
||||
};
|
||||
|
||||
// Update state with result
|
||||
if result == "Error" {
|
||||
first_num.set(String::new());
|
||||
} else {
|
||||
first_num.set(result);
|
||||
}
|
||||
|
||||
// Reset others
|
||||
second_num.set(String::new());
|
||||
operator.set(String::new());
|
||||
}
|
||||
Reference in New Issue
Block a user