better ui organisation

This commit is contained in:
Penwing 2024-01-25 08:48:32 +01:00
parent d53edc92e9
commit fcb1b7abba
7 changed files with 195 additions and 80 deletions

View file

@ -4,55 +4,34 @@ use std::{env, path::Path, cmp::max};
use crate::tools; use crate::tools;
use crate::Calcifer; use crate::Calcifer;
use crate::TIME_LABELS;
use crate::PATH_ROOT; use crate::PATH_ROOT;
use crate::MAX_TABS; use crate::MAX_TABS;
pub mod code_editor; pub mod code_editor;
use code_editor::CodeEditor; use code_editor::CodeEditor;
use code_editor::themes::DEFAULT_THEMES;
mod app_base; mod app_base;
impl Calcifer { impl Calcifer {
pub fn draw_settings(&mut self, ctx: &egui::Context) { pub fn draw_settings(&mut self, ctx: &egui::Context) {
egui::TopBottomPanel::top("settings") egui::SidePanel::left("settings")
.resizable(false) .resizable(false)
.exact_width(self.font_size * 1.8)
.show(ctx, |ui| { .show(ctx, |ui| {
ui.horizontal(|ui| { ui.vertical(|ui| {
if ui.add(egui::Button::new("open file")).clicked() { if ui.add(egui::Button::new("📁")).clicked() {
if let Some(path) = rfd::FileDialog::new().set_directory(Path::new(&PATH_ROOT)).pick_file() { if let Some(path) = rfd::FileDialog::new().set_directory(Path::new(&PATH_ROOT)).pick_file() {
self.open_file(Some(&path)); self.open_file(Some(&path));
} }
} }
ui.separator(); ui.separator();
self.tree_display = self.toggle(ui, self.tree_display, "🗐");
ui.label("Theme ");
egui::ComboBox::from_label("")
.selected_text(format!("{}", self.theme.name))
.show_ui(ui, |ui| {
ui.style_mut().wrap = Some(false);
ui.set_min_width(60.0);
for theme in DEFAULT_THEMES {
ui.selectable_value(&mut self.theme, theme, theme.name);
}
});
ui.separator(); ui.separator();
self.tree_display = self.toggle(ui, self.tree_display, "Tree"); self.settings_menu.visible = self.toggle(ui, self.settings_menu.visible, "");
ui.separator(); ui.separator();
self.debug_display = self.toggle(ui, self.debug_display, "Debug"); self.profiler_menu.visible = self.toggle(ui, self.profiler_menu.visible, "🗠");
ui.separator(); ui.separator();
if self.debug_display {
let combined_string: Vec<String> = TIME_LABELS.into_iter().zip(self.time_watch.clone().into_iter())
.map(|(s, v)| format!("{} : {:.1} ms", s, v)).collect();
let mut result = combined_string.join(" ; ");
result.push_str(&format!(" total : {:.1}", self.time_watch.clone().iter().sum::<f32>()));
ui.label(result);
}
}); });
}); });
} }
@ -202,4 +181,27 @@ impl Calcifer {
.with_numlines(true) .with_numlines(true)
.show(ui, &mut current_tab.code, &mut current_tab.saved, &mut current_tab.last_cursor, &mut current_tab.scroll_offset, override_cursor); .show(ui, &mut current_tab.code, &mut current_tab.saved, &mut current_tab.last_cursor, &mut current_tab.scroll_offset, override_cursor);
} }
pub fn draw_windows(&mut self, ctx: &egui::Context) {
if self.search.visible {
self.search.show(ctx, &mut self.tabs, &mut self.selected_tab);
}
if self.close_tab_confirm.visible {
self.close_tab_confirm.show(ctx);
}
if self.refresh_confirm.visible {
self.refresh_confirm.show(ctx);
}
if self.profiler_menu.visible {
self.profiler_menu.show(ctx, self.time_watch.clone());
}
if self.settings_menu.visible {
self.settings_menu.show(ctx);
}
if self.settings_menu.updated {
self.theme = self.settings_menu.theme.clone();
}
self.handle_confirm();
}
} }

View file

@ -1,5 +1,6 @@
use std::{path::PathBuf, fs, path::Path, cmp::min, io}; use std::{path::PathBuf, fs, path::Path, cmp::min, io};
use eframe::egui; use eframe::egui;
use egui::Color32;
use crate::Calcifer; use crate::Calcifer;
use crate::tools; use crate::tools;
@ -62,6 +63,7 @@ impl Calcifer {
let mut new = Self { let mut new = Self {
theme: DEFAULT_THEMES[min(app_state.theme, DEFAULT_THEMES.len() - 1)], theme: DEFAULT_THEMES[min(app_state.theme, DEFAULT_THEMES.len() - 1)],
tabs: Vec::new(), tabs: Vec::new(),
settings_menu: tools::settings::SettingsWindow::new(DEFAULT_THEMES[app_state.theme]),
..Default::default() ..Default::default()
}; };
@ -150,13 +152,13 @@ impl Calcifer {
pub fn toggle(&self, ui: &mut egui::Ui, display : bool, title : &str) -> bool { pub fn toggle(&self, ui: &mut egui::Ui, display : bool, title : &str) -> bool {
let text = if display.clone() { let color = if display.clone() {
format!("hide {}", title) Color32::from_hex(self.theme.functions).expect("Could not convert color to hex (functions)")
} else { } else {
format!("show {}", title) Color32::from_hex(self.theme.bg).expect("Could not convert color to hex (bg)")
}; };
if ui.add(egui::Button::new(text)).clicked() { if ui.add(egui::Button::new(title).fill(color)).clicked() {
return !display return !display
} }
return display return display

View file

@ -4,6 +4,9 @@ mod calcifer;
use eframe::egui; use eframe::egui;
use calcifer::code_editor::ColorTheme; use calcifer::code_editor::ColorTheme;
use std::{path::Path, sync::Arc, time, thread}; use std::{path::Path, sync::Arc, time, thread};
use egui::FontFamily::Proportional;
use egui::FontId;
use egui::TextStyle::{Small, Button, Body, Heading, Monospace};
use calcifer::code_editor::themes::DEFAULT_THEMES; use calcifer::code_editor::themes::DEFAULT_THEMES;
@ -24,7 +27,7 @@ use build::TITLE;
const TERMINAL_HEIGHT : f32 = 200.0; const TERMINAL_HEIGHT : f32 = 200.0;
const RED : egui::Color32 = egui::Color32::from_rgb(235, 108, 99); const RED : egui::Color32 = egui::Color32::from_rgb(235, 108, 99);
const TIME_LABELS : [&str; 5] = ["settings", "tree", "terminal", "tabs", "content"]; const TIME_LABELS : [&str; 7] = ["input", "settings", "tree", "terminal", "tabs", "content", "windows"];
const MAX_FPS : f32 = 30.0; const MAX_FPS : f32 = 30.0;
const PATH_ROOT : &str = "/home/penwing/Documents/"; const PATH_ROOT : &str = "/home/penwing/Documents/";
const DISPLAY_PATH_DEPTH : usize = 3; const DISPLAY_PATH_DEPTH : usize = 3;
@ -69,17 +72,18 @@ struct Calcifer {
theme: ColorTheme, theme: ColorTheme,
font_size: f32, font_size: f32,
search: tools::search::SearchWindow,
debug_display: bool,
time_watch: Vec<f32>,
next_frame: time::Instant,
tree_display: bool, tree_display: bool,
close_tab_confirm: tools::confirm::ConfirmWindow, close_tab_confirm: tools::confirm::ConfirmWindow,
tab_to_close: usize, tab_to_close: usize,
refresh_confirm: tools::confirm::ConfirmWindow, refresh_confirm: tools::confirm::ConfirmWindow,
search: tools::search::SearchWindow,
settings_menu: tools::settings::SettingsWindow,
profiler_menu: tools::profiler::ProfilerWindow,
time_watch: Vec<f32>,
next_frame: time::Instant,
} }
@ -95,17 +99,18 @@ impl Default for Calcifer {
theme: DEFAULT_THEMES[0], theme: DEFAULT_THEMES[0],
font_size: 14.0, font_size: 14.0,
search: tools::search::SearchWindow::default(),
debug_display: false,
time_watch: vec![0.0; TIME_LABELS.len()],
next_frame: time::Instant::now(),
tree_display: false, tree_display: false,
close_tab_confirm: tools::confirm::ConfirmWindow::new("You have some unsaved changes, Do you still want to close this document ?", "Confirm Close"), close_tab_confirm: tools::confirm::ConfirmWindow::new("You have some unsaved changes, Do you still want to close this document ?", "Confirm Close"),
tab_to_close: 0, tab_to_close: 0,
refresh_confirm: tools::confirm::ConfirmWindow::new("You have some unsaved changes, Do you still want to refresh this document ?", "Confirm Refresh"), refresh_confirm: tools::confirm::ConfirmWindow::new("You have some unsaved changes, Do you still want to refresh this document ?", "Confirm Refresh"),
search: tools::search::SearchWindow::default(),
settings_menu: tools::settings::SettingsWindow::new(DEFAULT_THEMES[0]),
profiler_menu: tools::profiler::ProfilerWindow::new(),
time_watch: vec![0.0; TIME_LABELS.len()],
next_frame: time::Instant::now(),
} }
} }
} }
@ -118,6 +123,17 @@ impl eframe::App for Calcifer {
let mut watch = time::Instant::now(); let mut watch = time::Instant::now();
let mut style = (*ctx.style()).clone();
style.text_styles = [
(Heading, FontId::new(self.font_size * 1.6, Proportional)),
(Body, FontId::new(self.font_size, Proportional)),
(Monospace, FontId::new(self.font_size, Proportional)),
(Button, FontId::new(self.font_size, Proportional)),
(Small, FontId::new(self.font_size, Proportional)),
]
.into();
ctx.set_style(style);
if ctx.input( |i| i.key_pressed(egui::Key::T) && i.modifiers.ctrl) && !self.refresh_confirm.visible { if ctx.input( |i| i.key_pressed(egui::Key::T) && i.modifiers.ctrl) && !self.refresh_confirm.visible {
if self.tabs[self.selected_tab.to_index()].saved { if self.tabs[self.selected_tab.to_index()].saved {
self.tabs[self.selected_tab.to_index()].refresh(); self.tabs[self.selected_tab.to_index()].refresh();
@ -155,35 +171,37 @@ impl eframe::App for Calcifer {
self.search.initialized = !self.search.visible.clone(); self.search.initialized = !self.search.visible.clone();
} }
self.draw_settings(ctx);
self.time_watch[0] = watch.elapsed().as_micros() as f32 / 1000.0; self.time_watch[0] = watch.elapsed().as_micros() as f32 / 1000.0;
watch = time::Instant::now(); watch = time::Instant::now();
self.draw_tree_panel(ctx); self.draw_settings(ctx);
self.time_watch[1] = watch.elapsed().as_micros() as f32 / 1000.0; self.time_watch[1] = watch.elapsed().as_micros() as f32 / 1000.0;
watch = time::Instant::now(); watch = time::Instant::now();
self.draw_terminal_panel(ctx); self.draw_tree_panel(ctx);
self.time_watch[2] = watch.elapsed().as_micros() as f32 / 1000.0; self.time_watch[2] = watch.elapsed().as_micros() as f32 / 1000.0;
watch = time::Instant::now(); watch = time::Instant::now();
self.draw_tab_panel(ctx); self.draw_terminal_panel(ctx);
self.time_watch[3] = watch.elapsed().as_micros() as f32 / 1000.0; self.time_watch[3] = watch.elapsed().as_micros() as f32 / 1000.0;
watch = time::Instant::now(); watch = time::Instant::now();
self.draw_content_panel(ctx); self.draw_tab_panel(ctx);
self.time_watch[4] = watch.elapsed().as_micros() as f32 / 1000.0; self.time_watch[4] = watch.elapsed().as_micros() as f32 / 1000.0;
watch = time::Instant::now();
self.search.show(ctx, &mut self.tabs, &mut self.selected_tab); self.draw_content_panel(ctx);
self.close_tab_confirm.show(ctx, &mut self.tabs, &mut self.selected_tab);
self.refresh_confirm.show(ctx, &mut self.tabs, &mut self.selected_tab);
self.handle_confirm(); self.time_watch[5] = watch.elapsed().as_micros() as f32 / 1000.0;
watch = time::Instant::now();
self.draw_windows(ctx);
self.time_watch[6] = watch.elapsed().as_micros() as f32 / 1000.0;
} }
fn on_exit(&mut self, _gl : std::option::Option<&eframe::glow::Context>) { fn on_exit(&mut self, _gl : std::option::Option<&eframe::glow::Context>) {

View file

@ -1,5 +1,4 @@
use eframe::egui; use eframe::egui;
use crate::tools::{Tab, TabNumber};
pub struct ConfirmWindow { pub struct ConfirmWindow {
@ -21,18 +20,18 @@ impl ConfirmWindow {
} }
pub fn show(&mut self, ctx: &egui::Context, tabs: &mut Vec<Tab>, selected_tab: &mut TabNumber) { pub fn show(&mut self, ctx: &egui::Context) {
let mut visible = self.visible.clone(); let mut visible = self.visible.clone();
egui::Window::new(self.id.clone()) egui::Window::new(self.id.clone())
.open(&mut visible) //I want it to be able to change its visibility (if user close manually) .open(&mut visible) //I want it to be able to change its visibility (if user close manually)
.vscroll(true) .vscroll(true)
.hscroll(true) .hscroll(true)
.show(ctx, |ui| self.ui(ui, tabs, selected_tab)); //but I want to edit the rest of the parameters and maybe close automatically .show(ctx, |ui| self.ui(ui)); //but I want to edit the rest of the parameters and maybe close automatically
self.visible = self.visible.clone() && visible; self.visible = self.visible.clone() && visible;
} }
fn ui(&mut self, ui: &mut egui::Ui, _tabs: &mut Vec<Tab>, _selected_tab: &mut TabNumber) { fn ui(&mut self, ui: &mut egui::Ui) {
ui.set_min_width(250.0); ui.set_min_width(250.0);
ui.label(self.prompt.clone()); ui.label(self.prompt.clone());
ui.vertical_centered(|ui| { ui.vertical_centered(|ui| {

View file

@ -8,6 +8,8 @@ use toml::Value;
//my tools; //my tools;
pub mod search; pub mod search;
pub mod confirm; pub mod confirm;
pub mod settings;
pub mod profiler;
pub mod terminal; pub mod terminal;
pub use terminal::*; pub use terminal::*;

38
src/tools/profiler.rs Normal file
View file

@ -0,0 +1,38 @@
use eframe::egui;
use crate::TIME_LABELS;
pub struct ProfilerWindow {
pub visible: bool,
}
impl ProfilerWindow {
pub fn new() -> Self {
Self {
visible: false,
}
}
pub fn show(&mut self, ctx: &egui::Context, time_watch: Vec<f32>) {
let mut visible = self.visible.clone();
egui::Window::new("Profiler")
.open(&mut visible) //I want it to be able to change its visibility (if user close manually)
.vscroll(true)
.hscroll(true)
.show(ctx, |ui| self.ui(ui, time_watch)); //but I want to edit the rest of the parameters and maybe close automatically
self.visible = self.visible.clone() && visible;
}
fn ui(&mut self, ui: &mut egui::Ui, time_watch: Vec<f32>) {
ui.set_min_width(100.0);
for (index, entry) in TIME_LABELS.iter().enumerate() {
ui.label(format!("{} : {:.1} ms", entry, time_watch[index]));
}
ui.separator();
ui.label(&format!("total : {:.1} ms", time_watch.clone().iter().sum::<f32>()));
}
}

54
src/tools/settings.rs Normal file
View file

@ -0,0 +1,54 @@
use eframe::egui;
use crate::ColorTheme;
use crate::DEFAULT_THEMES;
pub struct SettingsWindow {
pub visible: bool,
pub updated: bool,
pub theme: ColorTheme,
}
impl SettingsWindow {
pub fn new(theme : ColorTheme) -> Self {
Self {
visible: false,
updated: false,
theme,
}
}
pub fn show(&mut self, ctx: &egui::Context) {
let mut visible = self.visible.clone();
egui::Window::new("Settings")
.open(&mut visible) //I want it to be able to change its visibility (if user close manually)
.vscroll(true)
.hscroll(true)
.show(ctx, |ui| self.ui(ui)); //but I want to edit the rest of the parameters and maybe close automatically
self.visible = self.visible.clone() && visible;
}
fn ui(&mut self, ui: &mut egui::Ui) {
ui.set_min_width(250.0);
ui.horizontal(|ui| {
ui.label("Theme ");
let previous_theme = self.theme.clone();
egui::ComboBox::from_label("")
.selected_text(format!("{}", self.theme.name))
.show_ui(ui, |ui| {
ui.style_mut().wrap = Some(false);
ui.set_min_width(60.0);
for theme in DEFAULT_THEMES {
ui.selectable_value(&mut self.theme, theme, theme.name);
}
});
if self.theme != previous_theme {
self.updated = true;
}
});
}
}