more file extensions

This commit is contained in:
WanderingPenwing 2024-02-21 14:52:03 +01:00
parent c6bd2f32fd
commit 43f2ebb2ae

View file

@ -1,7 +1,7 @@
use eframe::egui; use eframe::egui;
use egui::{ use egui::{
FontFamily, FontId, FontFamily, FontId,
TextStyle::{Body, Button, Heading, Monospace, Small}, TextStyle::{Body, Button, Heading, Monospace, Small},
}; };
use homedir::get_my_home; use homedir::get_my_home;
use std::{ops::Range, path::PathBuf, sync::Arc, thread, time}; use std::{ops::Range, path::PathBuf, sync::Arc, thread, time};
@ -17,13 +17,13 @@ const TITLE: &str = " debug";
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
const TITLE: &str = ""; const TITLE: &str = "";
const ALLOWED_FILE_EXTENSIONS: [&str; 7] = ["", "rs", "toml", "txt", "project", "sh", "md"]; const ALLOWED_FILE_EXTENSIONS: [&str; 7] = ["", "rs", "toml", "txt", "project", "sh", "md", "html", "js", "css", "php", "py"];
const PROJECT_EXTENSION: &str = "project"; const PROJECT_EXTENSION: &str = "project";
const TERMINAL_HEIGHT: f32 = 200.0; const TERMINAL_HEIGHT: f32 = 200.0;
const TERMINAL_RANGE: Range<f32> = 100.0..600.0; const TERMINAL_RANGE: Range<f32> = 100.0..600.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; 7] = [ const TIME_LABELS: [&str; 7] = [
"input", "settings", "tree", "terminal", "tabs", "content", "windows", "input", "settings", "tree", "terminal", "tabs", "content", "windows",
]; ];
const MAX_FPS: f32 = 30.0; const MAX_FPS: f32 = 30.0;
const DISPLAY_PATH_DEPTH: usize = 3; const DISPLAY_PATH_DEPTH: usize = 3;
@ -31,269 +31,269 @@ const MAX_PROJECT_COLUMNS: usize = 8;
const RUNNING_COMMAND_REFRESH_DELAY: f32 = 0.1; const RUNNING_COMMAND_REFRESH_DELAY: f32 = 0.1;
fn main() -> Result<(), eframe::Error> { fn main() -> Result<(), eframe::Error> {
let icon_data = core::load_icon().unwrap_or_default(); let icon_data = core::load_icon().unwrap_or_default();
let options = eframe::NativeOptions { let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default() viewport: egui::ViewportBuilder::default()
.with_inner_size([1200.0, 800.0]) .with_inner_size([1200.0, 800.0])
.with_icon(Arc::new(icon_data)), .with_icon(Arc::new(icon_data)),
..Default::default() ..Default::default()
}; };
// Attempt to load previous state // Attempt to load previous state
let app_state: core::AppState = if save_path().exists() { let app_state: core::AppState = if save_path().exists() {
match core::load_state(save_path().as_path()) { match core::load_state(save_path().as_path()) {
Ok(app_state) => app_state, Ok(app_state) => app_state,
Err(_) => core::AppState::default(), Err(_) => core::AppState::default(),
} }
} else { } else {
core::AppState::default() core::AppState::default()
}; };
eframe::run_native( eframe::run_native(
&format!("Calcifer{}", TITLE), &format!("Calcifer{}", TITLE),
options, options,
Box::new(move |_cc| Box::from(Calcifer::from_app_state(app_state))), Box::new(move |_cc| Box::from(Calcifer::from_app_state(app_state))),
) )
} }
struct Calcifer { struct Calcifer {
selected_tab: usize, selected_tab: usize,
tabs: Vec<panels::Tab>, tabs: Vec<panels::Tab>,
command: String, command: String,
command_history: Vec<panels::CommandEntry>, command_history: Vec<panels::CommandEntry>,
running_command: bool, running_command: bool,
theme: editor::ColorTheme, theme: editor::ColorTheme,
font_size: f32, font_size: f32,
project_content: panels::Project, project_content: panels::Project,
home: PathBuf, home: PathBuf,
tree_dir_opened: Vec<String>, tree_dir_opened: Vec<String>,
file_tree: Option<panels::FileEntry>, file_tree: Option<panels::FileEntry>,
n_file_displayed: usize, n_file_displayed: usize,
tree_visible: bool, tree_visible: bool,
profiler_visible: bool, profiler_visible: bool,
terminal_visible: bool, terminal_visible: bool,
close_tab_confirm: sub_windows::ConfirmWindow, close_tab_confirm: sub_windows::ConfirmWindow,
tab_to_close: usize, tab_to_close: usize,
refresh_confirm: sub_windows::ConfirmWindow, refresh_confirm: sub_windows::ConfirmWindow,
exit_confirm: sub_windows::ConfirmWindow, exit_confirm: sub_windows::ConfirmWindow,
search_menu: sub_windows::SearchWindow, search_menu: sub_windows::SearchWindow,
settings_menu: sub_windows::SettingsWindow, settings_menu: sub_windows::SettingsWindow,
shortcuts_menu: sub_windows::ShortcutsWindow, shortcuts_menu: sub_windows::ShortcutsWindow,
time_watch: Vec<f32>, time_watch: Vec<f32>,
next_frame: time::Instant, next_frame: time::Instant,
} }
impl Default for Calcifer { impl Default for Calcifer {
fn default() -> Self { fn default() -> Self {
Self { Self {
selected_tab: 0, selected_tab: 0,
tabs: vec![panels::Tab::default()], tabs: vec![panels::Tab::default()],
command: String::new(), command: String::new(),
command_history: Vec::new(), command_history: Vec::new(),
running_command: false, running_command: false,
theme: editor::themes::DEFAULT_THEMES[0], theme: editor::themes::DEFAULT_THEMES[0],
font_size: 14.0, font_size: 14.0,
project_content: panels::Project::new(), project_content: panels::Project::new(),
home: get_my_home().unwrap().unwrap(), home: get_my_home().unwrap().unwrap(),
tree_dir_opened: vec![], tree_dir_opened: vec![],
file_tree: None, file_tree: None,
n_file_displayed: 0, n_file_displayed: 0,
tree_visible: false, tree_visible: false,
profiler_visible: false, profiler_visible: false,
terminal_visible: false, terminal_visible: false,
close_tab_confirm: sub_windows::ConfirmWindow::new( close_tab_confirm: sub_windows::ConfirmWindow::new(
"You have some unsaved changes, Do you still want to close this document ?", "You have some unsaved changes, Do you still want to close this document ?",
"Confirm Close", "Confirm Close",
), ),
tab_to_close: 0, tab_to_close: 0,
refresh_confirm: sub_windows::ConfirmWindow::new( refresh_confirm: sub_windows::ConfirmWindow::new(
"You have some unsaved changes, Do you still want to refresh this document ?", "You have some unsaved changes, Do you still want to refresh this document ?",
"Confirm Refresh", "Confirm Refresh",
), ),
exit_confirm: sub_windows::ConfirmWindow::new("", "Confirm Exit"), exit_confirm: sub_windows::ConfirmWindow::new("", "Confirm Exit"),
search_menu: sub_windows::SearchWindow::default(), search_menu: sub_windows::SearchWindow::default(),
settings_menu: sub_windows::SettingsWindow::new(editor::themes::DEFAULT_THEMES[0]), settings_menu: sub_windows::SettingsWindow::new(editor::themes::DEFAULT_THEMES[0]),
shortcuts_menu: sub_windows::ShortcutsWindow::new(), shortcuts_menu: sub_windows::ShortcutsWindow::new(),
time_watch: vec![0.0; TIME_LABELS.len()], time_watch: vec![0.0; TIME_LABELS.len()],
next_frame: time::Instant::now(), next_frame: time::Instant::now(),
} }
} }
} }
impl eframe::App for Calcifer { impl eframe::App for Calcifer {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
thread::sleep(time::Duration::from_secs_f32( thread::sleep(time::Duration::from_secs_f32(
((1.0 / MAX_FPS) - self.next_frame.elapsed().as_secs_f32()).max(0.0), ((1.0 / MAX_FPS) - self.next_frame.elapsed().as_secs_f32()).max(0.0),
)); ));
self.next_frame = time::Instant::now(); self.next_frame = time::Instant::now();
let mut watch = time::Instant::now(); let mut watch = time::Instant::now();
let mut style = (*ctx.style()).clone(); let mut style = (*ctx.style()).clone();
style.text_styles = [ style.text_styles = [
( (
Heading, Heading,
FontId::new(self.font_size * 1.6, FontFamily::Proportional), FontId::new(self.font_size * 1.6, FontFamily::Proportional),
), ),
(Body, FontId::new(self.font_size, FontFamily::Proportional)), (Body, FontId::new(self.font_size, FontFamily::Proportional)),
( (
Monospace, Monospace,
FontId::new(self.font_size, FontFamily::Monospace), FontId::new(self.font_size, FontFamily::Monospace),
), ),
( (
Button, Button,
FontId::new(self.font_size, FontFamily::Proportional), FontId::new(self.font_size, FontFamily::Proportional),
), ),
(Small, FontId::new(self.font_size, FontFamily::Proportional)), (Small, FontId::new(self.font_size, FontFamily::Proportional)),
] ]
.into(); .into();
ctx.set_style(style); ctx.set_style(style);
if ctx.input(|i| i.key_pressed(egui::Key::R) && i.modifiers.ctrl) if ctx.input(|i| i.key_pressed(egui::Key::R) && i.modifiers.ctrl)
&& !self.refresh_confirm.visible && !self.refresh_confirm.visible
{ {
if self.tabs[self.selected_tab].saved { if self.tabs[self.selected_tab].saved {
self.tabs[self.selected_tab].refresh(); self.tabs[self.selected_tab].refresh();
} else { } else {
self.refresh_confirm.ask(); self.refresh_confirm.ask();
} }
} }
if ctx.input(|i| i.key_pressed(egui::Key::Enter)) if ctx.input(|i| i.key_pressed(egui::Key::Enter))
&& self.tabs[self.selected_tab].language == PROJECT_EXTENSION && self.tabs[self.selected_tab].language == PROJECT_EXTENSION
{ {
self.project_content.item_window.visible = true; self.project_content.item_window.visible = true;
} }
if ctx.input(|i| i.key_pressed(egui::Key::S) && i.modifiers.ctrl) { if ctx.input(|i| i.key_pressed(egui::Key::S) && i.modifiers.ctrl) {
self.handle_save_file(self.save_tab()); self.handle_save_file(self.save_tab());
} }
if ctx.input(|i| i.key_pressed(egui::Key::S) && i.modifiers.ctrl && i.modifiers.shift) { if ctx.input(|i| i.key_pressed(egui::Key::S) && i.modifiers.ctrl && i.modifiers.shift) {
self.handle_save_file(self.save_tab_as()); self.handle_save_file(self.save_tab_as());
} }
if ctx.input(|i| i.key_pressed(egui::Key::ArrowLeft) && i.modifiers.alt) { if ctx.input(|i| i.key_pressed(egui::Key::ArrowLeft) && i.modifiers.alt) {
self.move_through_tabs(false); self.move_through_tabs(false);
} }
if ctx.input(|i| i.key_pressed(egui::Key::ArrowRight) && i.modifiers.alt) { if ctx.input(|i| i.key_pressed(egui::Key::ArrowRight) && i.modifiers.alt) {
self.move_through_tabs(true); self.move_through_tabs(true);
} }
if ctx.input(|i| i.zoom_delta() > 1.0) { if ctx.input(|i| i.zoom_delta() > 1.0) {
self.font_size = (self.font_size * 1.1).min(30.0); self.font_size = (self.font_size * 1.1).min(30.0);
} }
if ctx.input(|i| i.zoom_delta() < 1.0) { if ctx.input(|i| i.zoom_delta() < 1.0) {
self.font_size = (self.font_size / 1.1).max(10.0); self.font_size = (self.font_size / 1.1).max(10.0);
} }
if ctx.input(|i| i.key_pressed(egui::Key::F) && i.modifiers.ctrl) { if ctx.input(|i| i.key_pressed(egui::Key::F) && i.modifiers.ctrl) {
self.search_menu.visible = !self.search_menu.visible; self.search_menu.visible = !self.search_menu.visible;
self.search_menu.initialized = !self.search_menu.visible; self.search_menu.initialized = !self.search_menu.visible;
} }
if ctx.input(|i| i.viewport().close_requested()) { if ctx.input(|i| i.viewport().close_requested()) {
let mut unsaved_tabs: Vec<usize> = vec![]; let mut unsaved_tabs: Vec<usize> = vec![];
for (index, tab) in self.tabs.iter().enumerate() { for (index, tab) in self.tabs.iter().enumerate() {
if !tab.saved { if !tab.saved {
unsaved_tabs.push(index); unsaved_tabs.push(index);
} }
} }
if !unsaved_tabs.is_empty() { if !unsaved_tabs.is_empty() {
let mut unsaved_tabs_names: String = "".to_string(); let mut unsaved_tabs_names: String = "".to_string();
for index in unsaved_tabs.iter() { for index in unsaved_tabs.iter() {
unsaved_tabs_names.push_str(&self.tabs[*index].get_name()); unsaved_tabs_names.push_str(&self.tabs[*index].get_name());
} }
egui::Context::send_viewport_cmd(ctx, egui::ViewportCommand::CancelClose); egui::Context::send_viewport_cmd(ctx, egui::ViewportCommand::CancelClose);
self.exit_confirm.prompt = format!( self.exit_confirm.prompt = format!(
"You have some unsaved changes :\n{}\nDo you still want to exit ?", "You have some unsaved changes :\n{}\nDo you still want to exit ?",
unsaved_tabs_names unsaved_tabs_names
); );
self.exit_confirm.ask(); self.exit_confirm.ask();
} }
} }
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_settings(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_tree_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_bottom_tray(ctx); self.draw_bottom_tray(ctx);
self.draw_terminal_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_tab_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(); watch = time::Instant::now();
self.draw_content_panel(ctx); self.draw_content_panel(ctx);
self.time_watch[5] = watch.elapsed().as_micros() as f32 / 1000.0; self.time_watch[5] = watch.elapsed().as_micros() as f32 / 1000.0;
watch = time::Instant::now(); watch = time::Instant::now();
self.draw_windows(ctx); self.draw_windows(ctx);
self.time_watch[6] = watch.elapsed().as_micros() as f32 / 1000.0; self.time_watch[6] = watch.elapsed().as_micros() as f32 / 1000.0;
if self.running_command && !ctx.input(|i| i.wants_repaint()) { if self.running_command && !ctx.input(|i| i.wants_repaint()) {
thread::sleep(time::Duration::from_secs_f32(RUNNING_COMMAND_REFRESH_DELAY)); thread::sleep(time::Duration::from_secs_f32(RUNNING_COMMAND_REFRESH_DELAY));
egui::Context::request_repaint(ctx); egui::Context::request_repaint(ctx);
} }
} }
fn on_exit(&mut self, _gl: std::option::Option<&eframe::glow::Context>) { fn on_exit(&mut self, _gl: std::option::Option<&eframe::glow::Context>) {
self.save_state(); self.save_state();
} }
} }
//save path //save path
fn save_path() -> PathBuf { fn save_path() -> PathBuf {
if TITLE.is_empty() { if TITLE.is_empty() {
get_my_home() get_my_home()
.unwrap() .unwrap()
.unwrap() .unwrap()
.as_path() .as_path()
.join(".calcifer") .join(".calcifer")
.join("save.json") .join("save.json")
.to_path_buf() .to_path_buf()
} else { } else {
get_my_home() get_my_home()
.unwrap() .unwrap()
.unwrap() .unwrap()
.as_path() .as_path()
.join(".calcifer") .join(".calcifer")
.join("debug") .join("debug")
.join("save.json") .join("save.json")
.to_path_buf() .to_path_buf()
} }
} }