From 5769965c6c6d2a8b62caa8598712cc95632007f2 Mon Sep 17 00:00:00 2001 From: Penwing Date: Mon, 22 Jan 2024 09:11:54 +0100 Subject: [PATCH] added search window --- README.md | 12 ++++++ src/main.rs | 21 ++++++++- src/tools/mod.rs | 27 ++++++++++-- src/tools/search.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 src/tools/search.rs diff --git a/README.md b/README.md index 38ef260..ee6fe76 100644 --- a/README.md +++ b/README.md @@ -1 +1,13 @@ # Calcifer + +My cutsom code editor (only the features I want inside) + +# 1.0 : +Added a File Tree +Added Tabs +Added an Embedded Terminal +Added Syntax Highlighting +Added Themes + +# 1.1 : +Better Terminal diff --git a/src/main.rs b/src/main.rs index 2acff12..a37f03c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod calcifer; use eframe::egui; use egui_code_editor::ColorTheme; use std::{path::Path, sync::Arc}; +use tools::Demo; const TERMINAL_HEIGHT : f32 = 200.0; const RED : egui::Color32 = egui::Color32::from_rgb(235, 108, 99); @@ -37,7 +38,7 @@ fn main() -> Result<(), eframe::Error> { } eframe::run_native( - "Calcifer", + "Calcifer v1.1", options, Box::new(move |_cc| Box::from(Calcifer::from_app_state(app_state))), ) @@ -47,9 +48,14 @@ fn main() -> Result<(), eframe::Error> { struct Calcifer { selected_tab : tools::TabNumber, tabs: Vec, + command: String, command_history: Vec, + theme: ColorTheme, + + search: tools::search::SearchWindow, + searching: bool, } @@ -58,9 +64,14 @@ impl Default for Calcifer { Self { selected_tab: tools::TabNumber::Zero, tabs: vec![tools::Tab::default()], + command: String::new(), command_history: Vec::new(), + theme: tools::themes::CustomColorTheme::fire(), + + search: tools::search::SearchWindow::default(), + searching: false, } } } @@ -79,12 +90,20 @@ impl eframe::App for Calcifer { if ctx.input( |i| i.key_pressed(egui::Key::Z) && i.modifiers.ctrl) { self.undo(); } + + if ctx.input( |i| i.key_pressed(egui::Key::F) && i.modifiers.ctrl) { + self.searching = !self.searching.clone(); + } self.draw_settings(ctx); self.draw_tree_panel(ctx); self.draw_terminal_panel(ctx); self.draw_tab_panel(ctx); self.draw_content_panel(ctx); + + if self.searching { + self.search.show(ctx, &mut self.searching, &mut self.tabs, &mut self.selected_tab); + } } fn on_exit(&mut self, _gl : std::option::Option<&eframe::glow::Context>) { diff --git a/src/tools/mod.rs b/src/tools/mod.rs index 42c4f92..3099b5a 100644 --- a/src/tools/mod.rs +++ b/src/tools/mod.rs @@ -1,9 +1,30 @@ use std::{process::Command, cmp::Ordering, env, path::PathBuf, fs::read_to_string, fs::write}; use egui_code_editor::Syntax; -use eframe::egui::IconData; +use eframe::egui; use serde::{Serialize, Deserialize}; pub mod themes; +pub mod search; + + +pub trait View { + fn ui(&mut self, ui: &mut egui::Ui); +} + +/// Something to view +pub trait Demo { + /// Is the demo enabled for this integraton? + fn is_enabled(&self, _ctx: &egui::Context) -> bool { + true + } + + /// `&'static` so we can also use it as a key to store open/close state. + fn name(&self) -> &str; //'static + + /// Show windows, etc + fn show(&mut self, ctx: &egui::Context, open: &mut bool, tabs: &mut Vec, selected_tab: &mut TabNumber); +} + #[derive(Debug, PartialEq, Eq)] pub enum TabNumber { @@ -125,7 +146,7 @@ pub fn loaded() { println!("Tools loaded"); } -pub fn load_icon() -> IconData { +pub fn load_icon() -> egui::IconData { let (icon_rgba, icon_width, icon_height) = { let icon = include_bytes!("../../assets/icon.png"); let image = image::load_from_memory(icon) @@ -136,7 +157,7 @@ pub fn load_icon() -> IconData { (rgba, width, height) }; - IconData { + egui::IconData { rgba: icon_rgba, width: icon_width, height: icon_height, diff --git a/src/tools/search.rs b/src/tools/search.rs new file mode 100644 index 0000000..bca0b40 --- /dev/null +++ b/src/tools/search.rs @@ -0,0 +1,101 @@ +use eframe::egui; +use crate::tools::{View, Demo, Tab, TabNumber}; + + +pub struct Selection { + pub start: usize, + pub end: usize, +} + + +impl Default for Selection { + fn default() -> Self { + Self { + start: 0, + end: 0, + } + } +} + + +pub struct SearchWindow { + search_text: String, + result: Selection, + across_documents: bool, + replace_text: String, +} + + +impl Default for SearchWindow { + fn default() -> Self { + Self { + search_text: "".into(), + result: Selection::default(), + across_documents: false, + replace_text: "".into(), + } + } +} + + +impl Demo for SearchWindow { + fn name(&self) -> &str { //'static + "Search" + } + + fn show(&mut self, ctx: &egui::Context, open: &mut bool, tabs: &mut Vec, selected_tab: &mut TabNumber) { + egui::Window::new(self.name()) + .open(open) + .vscroll(true) + .hscroll(true) + .show(ctx, |ui| self.ui(ui)); + } +} + + +impl View for SearchWindow { + fn ui(&mut self, ui: &mut egui::Ui) { + ui.set_min_width(250.0); + + ui.horizontal(|ui| { + let Self { search_text, .. } = self; + ui.add(egui::TextEdit::singleline(search_text).desired_width(120.0).lock_focus(true)); + + if ui.add(egui::Button::new("<")).clicked() { + self.find_previous(); + } + + if ui.add(egui::Button::new(">")).clicked() { + self.find_next(); + } + }); + + ui.checkbox(&mut self.across_documents, "Across documents"); + + egui::CollapsingHeader::new("Replace") + .default_open(false) + .show(ui, |ui| { + ui.horizontal(|ui| { + let Self { replace_text, .. } = self; + ui.add(egui::TextEdit::singleline(replace_text).desired_width(120.0).lock_focus(true)); + if ui.add(egui::Button::new("Replace")).clicked() { + self.replace_text(); + } + }); + }); + } +} + +impl SearchWindow { + fn find_previous(&self) { + println!("Searched for previous"); + } + + fn find_next(&self) { + println!("Searched for next"); + } + + fn replace_text(&self) { + println!("Searched to replace {} with {}", &self.search_text, &self.replace_text); + } +} \ No newline at end of file