calculatrice pour mon systeme debian

This commit is contained in:
2025-10-18 23:14:29 +02:00
commit 6f6edaedba
5 changed files with 4412 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

4212
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

8
Cargo.toml Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 KiB

191
src/main.rs Normal file
View 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();
}
});
}
}