calculatrice pour mon systeme debian
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
4212
Cargo.lock
generated
Normal file
4212
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "calculator"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
eframe = "0.33.0"
|
||||||
|
egui_extras = "0.33.0"
|
||||||
BIN
assets/icon.png
Normal file
BIN
assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 711 KiB |
191
src/main.rs
Normal file
191
src/main.rs
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
use eframe::egui::{self, Align, Key};
|
||||||
|
use egui_extras::{Column, TableBuilder};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let native_options = eframe::NativeOptions {
|
||||||
|
viewport: egui::ViewportBuilder::default()
|
||||||
|
.with_inner_size([400.0, 600.0])
|
||||||
|
.with_icon(
|
||||||
|
// Charger l'icône depuis des bytes PNG
|
||||||
|
eframe::icon_data::from_png_bytes(include_bytes!("../assets/icon.png"))
|
||||||
|
.expect("Failed to load icon"),
|
||||||
|
),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let _ = eframe::run_native(
|
||||||
|
"Calculator",
|
||||||
|
native_options,
|
||||||
|
Box::new(|cc| Ok(Box::new(Calculator::new(cc)))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Calculator {
|
||||||
|
input: String,
|
||||||
|
result: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Calculator {
|
||||||
|
fn new(_cc: &eframe::CreationContext<'_>) -> Self {
|
||||||
|
Self {
|
||||||
|
input: String::new(),
|
||||||
|
result: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate(&mut self) {
|
||||||
|
let mut numbers: Vec<f32> = Vec::new();
|
||||||
|
let mut operators: Vec<char> = Vec::new();
|
||||||
|
let mut number_buffer = String::new();
|
||||||
|
|
||||||
|
// Parser l'input pour extraire nombres et opérateurs
|
||||||
|
for character in self.input.chars() {
|
||||||
|
match character {
|
||||||
|
'0'..='9' | '.' => {
|
||||||
|
number_buffer.push(character);
|
||||||
|
}
|
||||||
|
'+' | '-' | '*' | '/' => {
|
||||||
|
if !number_buffer.is_empty() {
|
||||||
|
numbers.push(Self::parse(number_buffer.clone()));
|
||||||
|
number_buffer.clear();
|
||||||
|
}
|
||||||
|
operators.push(character);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajouter le dernier nombre
|
||||||
|
if !number_buffer.is_empty() {
|
||||||
|
numbers.push(Self::parse(number_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier qu'on a des nombres à calculer
|
||||||
|
if numbers.is_empty() {
|
||||||
|
self.result = "Erreur".to_string();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gérer les priorités des opérateurs (d'abord * et /)
|
||||||
|
let mut nums = numbers;
|
||||||
|
let mut ops = operators;
|
||||||
|
|
||||||
|
// Première passe: multiplication et division
|
||||||
|
let mut i = 0;
|
||||||
|
while i < ops.len() {
|
||||||
|
if ops[i] == '*' || ops[i] == '/' {
|
||||||
|
let left = nums[i];
|
||||||
|
let right = nums[i + 1];
|
||||||
|
let result = if ops[i] == '*' {
|
||||||
|
left * right
|
||||||
|
} else {
|
||||||
|
if right == 0.0 {
|
||||||
|
self.result = "Erreur: division par zéro".to_string();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
left / right
|
||||||
|
};
|
||||||
|
nums[i] = result;
|
||||||
|
nums.remove(i + 1);
|
||||||
|
ops.remove(i);
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deuxième passe: addition et soustraction
|
||||||
|
let mut result = nums[0];
|
||||||
|
for (i, op) in ops.iter().enumerate() {
|
||||||
|
match op {
|
||||||
|
'+' => result += nums[i + 1],
|
||||||
|
'-' => result -= nums[i + 1],
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.result = result.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: String) -> f32 {
|
||||||
|
input.parse::<f32>().unwrap_or(0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl eframe::App for Calculator {
|
||||||
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
|
egui::TopBottomPanel::top("input").show(ctx, |ui| {
|
||||||
|
let window_size = ctx.screen_rect().size();
|
||||||
|
// Le panneau du haut prend 1/3 de la hauteur totale
|
||||||
|
let widget_height = window_size.y / 3.0;
|
||||||
|
let widget_size = egui::Vec2::new(window_size.x - 20.0, widget_height - 40.0);
|
||||||
|
|
||||||
|
// Taille de police proportionnelle
|
||||||
|
let font_size = widget_height * 0.4;
|
||||||
|
|
||||||
|
ui.add(
|
||||||
|
egui::TextEdit::singleline(&mut self.input)
|
||||||
|
.hint_text("Type here...")
|
||||||
|
.min_size(widget_size)
|
||||||
|
.horizontal_align(Align::RIGHT)
|
||||||
|
.font(egui::FontId::proportional(font_size)),
|
||||||
|
);
|
||||||
|
ui.add(
|
||||||
|
egui::Label::new(egui::RichText::new(&self.result).size(40.0)).halign(Align::Max),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
let available_size = ui.available_size();
|
||||||
|
let symbols: [char; 16] = [
|
||||||
|
'1', '2', '3', '+', '4', '5', '6', '-', '7', '8', '9', '*', '.', '0', 'C', '/',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Calcul des dimensions de la grille
|
||||||
|
let grid_padding = 10.0;
|
||||||
|
let button_spacing = 5.0;
|
||||||
|
let cell_width = (available_size.x - grid_padding * 2.0) / 4.0;
|
||||||
|
let cell_height = (available_size.y - grid_padding * 2.0) / 4.0;
|
||||||
|
let button_size =
|
||||||
|
egui::Vec2::new(cell_width - button_spacing, cell_height - button_spacing);
|
||||||
|
|
||||||
|
// Calculer la taille de police des boutons proportionnellement
|
||||||
|
let button_font_size = (button_size.y * 0.4).min(button_size.x * 0.3);
|
||||||
|
|
||||||
|
ui.add_space(grid_padding);
|
||||||
|
|
||||||
|
let mut table = TableBuilder::new(ui)
|
||||||
|
.cell_layout(egui::Layout::centered_and_justified(
|
||||||
|
egui::Direction::TopDown,
|
||||||
|
))
|
||||||
|
.columns(Column::exact(cell_width), 4);
|
||||||
|
|
||||||
|
table.body(|mut body| {
|
||||||
|
body.rows(cell_height, 4, |mut row| {
|
||||||
|
let row_index = row.index();
|
||||||
|
for col_index in 0..4 {
|
||||||
|
row.col(|ui| {
|
||||||
|
let button_index = row_index * 4 + col_index;
|
||||||
|
let response = ui.add_sized(
|
||||||
|
button_size,
|
||||||
|
egui::Button::new(
|
||||||
|
egui::RichText::new(symbols[button_index].to_string())
|
||||||
|
.size(button_font_size),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if response.clicked() {
|
||||||
|
if symbols[button_index] == 'C' {
|
||||||
|
self.input.clear();
|
||||||
|
} else {
|
||||||
|
self.input.push(symbols[button_index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if ctx.input(|i| i.key_pressed(Key::Enter)) {
|
||||||
|
self.calculate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user