[lab1] Total gui refactoring

This commit is contained in:
Andrew Golovashevich 2026-02-15 20:52:13 +03:00
parent 0aafa08ddb
commit bab6598a0d
5 changed files with 146 additions and 134 deletions

41
lab1/src/gui/board.rs Normal file
View File

@ -0,0 +1,41 @@
use eframe::egui::{Color32, CornerRadius, Pos2, Rect, Ui, Vec2};
use crate::algo::Board;
pub(crate) fn get_board_size(board_size: usize) -> Vec2 {
return Vec2::new(10.0 * board_size as f32, 10.0 * board_size as f32);
}
pub(crate) fn draw_board(ui: &mut Ui, board: &Board) {
let painter = ui.painter();
painter.rect_filled(
ui.available_rect_before_wrap(),
CornerRadius::from(0),
Color32::from_rgb(50, 50, 150),
);
for y in 0..board.len() {
for x in 0..board.len() {
if y % 2 == x % 2 {
painter.rect_filled(
Rect::from_min_max(
Pos2::new((10 * x) as f32, (10 * y) as f32),
Pos2::new(
(10 * (x + 1)) as f32,
(10 * (y + 1)) as f32,
),
),
CornerRadius::from(0),
Color32::from_rgb(200, 200, 255),
);
}
}
}
for i in 0..board.len() {
painter.circle_filled(
Pos2::new((10 * board[i] + 5) as f32, (10 * i + 5) as f32),
3.0,
Color32::from_rgb(255, 50, 0),
);
}
}

24
lab1/src/gui/data.rs Normal file
View File

@ -0,0 +1,24 @@
use crate::algo::{AnnealingConfig, Board};
pub(crate) struct MyApp {
pub simulationConfig: AnnealingConfig,
pub boardSize: usize,
pub _isFirstFrame: bool,
pub result: Option<Board>,
}
impl MyApp {
pub(crate) fn new() -> Self {
return Self {
simulationConfig: AnnealingConfig {
initialTemperature: 30.0,
targetTemperature: 0.5,
cooldownCoefficient: 0.99,
iterationsPerAge: 100,
},
boardSize: 20,
_isFirstFrame: true,
result: None,
};
}
}

54
lab1/src/gui/input.rs Normal file
View File

@ -0,0 +1,54 @@
use crate::algo;
use crate::gui::data::MyApp;
use bgtu_ai_utility::gui::labeled_slider;
use eframe::egui::Ui;
use rand::rng;
pub(crate) fn input(ui: &mut Ui, data: &mut MyApp) {
ui.add_enabled_ui(matches!(data.result, None), |ui| {
labeled_slider(ui, "Board size:", &mut data.boardSize, 2..=50, 1.0);
ui.label("");
labeled_slider(
ui,
"Initial temperature:",
&mut data.simulationConfig.initialTemperature,
data.simulationConfig.targetTemperature + 0.01..=100.0,
0.01,
);
ui.label("");
labeled_slider(
ui,
"Target Temperature:",
&mut data.simulationConfig.targetTemperature,
0.0..=data.simulationConfig.initialTemperature - 0.1,
0.01,
);
ui.label("");
labeled_slider(
ui,
"Cooldown coefficient:",
&mut data.simulationConfig.cooldownCoefficient,
0.001..=0.999,
0.001,
);
ui.label("");
labeled_slider(
ui,
"Iterations per age:",
&mut data.simulationConfig.iterationsPerAge,
1..=1000,
1.0,
);
ui.label("");
if ui.button("Calculate").clicked() {
data.result = Some(algo::simulateAnnealing(
data.boardSize,
&data.simulationConfig,
&mut rng(),
))
}
});
}

7
lab1/src/gui/mod.rs Normal file
View File

@ -0,0 +1,7 @@
mod input;
mod data;
mod board;
pub(crate) use board::{draw_board, get_board_size};
pub(crate) use data::MyApp;
pub(crate) use input::input;

View File

@ -1,150 +1,36 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
mod algo;
mod gui;
use bgtu_ai_utility::gui::{boot_eframe, labeled_slider};
use bgtu_ai_utility::gui::{boot_eframe, subwindow};
use eframe::egui;
use eframe::egui::{CornerRadius, Frame};
use eframe::epaint::{Color32, Pos2, Rect};
use rand::SeedableRng;
use std::time::{SystemTime, UNIX_EPOCH};
fn main() -> eframe::Result {
return boot_eframe(||MyApp::new())
return boot_eframe(|| gui::MyApp::new());
}
struct MyApp {
simulationConfig: algo::AnnealingConfig,
boardSize: usize,
_isFirstFrame: bool,
result: Option<algo::Board>,
}
impl MyApp {
fn new() -> Self {
return Self {
simulationConfig: algo::AnnealingConfig {
initialTemperature: 30.0,
targetTemperature: 0.5,
cooldownCoefficient: 0.99,
iterationsPerAge: 100,
},
boardSize: 20,
_isFirstFrame: true,
result: None,
}
}
}
impl eframe::App for MyApp {
impl eframe::App for gui::MyApp {
fn update(&mut self, ui: &eframe::egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ui, |ui| {
ui.add_enabled_ui(matches!(self.result, None), |ui| {
labeled_slider(ui, "Board size:", &mut self.boardSize, 2..=50, 1.0);
ui.label("");
gui::input(ui, self);
labeled_slider(
ui,
"Initial temperature:",
&mut self.simulationConfig.initialTemperature,
self.simulationConfig.targetTemperature + 0.01..=100.0,
0.01,
);
ui.label("");
labeled_slider(
ui,
"Target Temperature:",
&mut self.simulationConfig.targetTemperature,
0.0..=self.simulationConfig.initialTemperature - 0.1,
0.01,
);
ui.label("");
labeled_slider(
ui,
"Cooldown coefficient:",
&mut self.simulationConfig.cooldownCoefficient,
0.001..=0.999,
0.001,
);
ui.label("");
labeled_slider(
ui,
"Iterations per age:",
&mut self.simulationConfig.iterationsPerAge,
1..=1000,
1.0,
);
ui.label("");
if ui.button("Calculate").clicked() {
self.result = Some(algo::simulateAnnealing(
self.boardSize,
&self.simulationConfig,
&mut rand::rngs::SmallRng::seed_from_u64(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs(),
),
))
}
});
match self.result.clone() {
match &self.result {
None => {}
Some(board) => ui.ctx().show_viewport_immediate(
egui::ViewportId::from_hash_of("board"),
egui::ViewportBuilder::default()
.with_title("Board")
.with_inner_size([
10.0 * self.boardSize as f32,
10.0 * self.boardSize as f32,
])
.with_resizable(false),
|ui, _| {
egui::CentralPanel::default()
.frame(Frame::default().inner_margin(0.0))
.show(ui, |ui| {
let painter = ui.painter();
painter.rect_filled(
ui.available_rect_before_wrap(),
CornerRadius::from(0),
Color32::from_rgb(50, 50, 150),
);
for y in 0..self.boardSize {
for x in 0..self.boardSize {
if y % 2 == x % 2 {
painter.rect_filled(
Rect::from_min_max(
Pos2::new((10 * x) as f32, (10 * y) as f32),
Pos2::new(
(10 * (x + 1)) as f32,
(10 * (y + 1)) as f32,
),
),
CornerRadius::from(0),
Color32::from_rgb(200, 200, 255),
);
}
}
}
for i in 0..self.boardSize {
painter.circle_filled(
Pos2::new((10 * board[i] + 5) as f32, (10 * i + 5) as f32),
3.0,
Color32::from_rgb(255, 50, 0),
);
}
if ui.input(|i| i.viewport().close_requested()) {
self.result = None
}
});
Some(board) => {
subwindow(
ui,
"board",
"Board",
|vb| {
return vb
.with_inner_size(gui::get_board_size(self.boardSize))
.with_resizable(false);
},
),
|ui| gui::draw_board(ui, board),
)
.on_close(|| self.result = None);
}
};
});
}