From 7da9928548b0d1516ba89b69dba4a5ed396339e9 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sun, 2 May 2021 19:28:02 +0200 Subject: [PATCH] Clean up new code editor code --- CHANGELOG.md | 1 + egui/src/ui.rs | 7 ---- egui/src/widgets/text_edit.rs | 48 +++++++++----------------- egui_demo_lib/src/apps/demo/widgets.rs | 42 +++++++--------------- epaint/src/text/font.rs | 2 +- epaint/src/text/mod.rs | 2 +- 6 files changed, 33 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34f0e38f..82e3776b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [ * Add anchors to windows and areas so you can put a window in e.g. the top right corner. * Make labels interactive with `Label::sense(Sense::click())`. * Add `Response::request_focus` and `Response::surrender_focus`. +* Add `TextEdit::code_editor` (VERY basic) * [Pan and zoom plots](https://github.com/emilk/egui/pull/317). * [Users can now store custom state in `egui::Memory`.](https://github.com/emilk/egui/pull/257). * Zoom input: ctrl-scroll and (on `egui_web`) trackpad-pinch gesture. diff --git a/egui/src/ui.rs b/egui/src/ui.rs index 48d28815..b3f35c8e 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -943,13 +943,6 @@ impl Ui { self.add(TextEdit::multiline(text).code_editor()) } - /// A `TextEdit` for code editing with configurable `Tab` management. - /// - /// Se also [`TextEdit::code_editor_with_config`]. - pub fn code_editor_with_config(&mut self, text: &mut String, config: CodingConfig) -> Response { - self.add(TextEdit::multiline(text).code_editor_with_config(config)) - } - /// Usage: `if ui.button("Click me").clicked() { … }` /// /// Shortcut for `add(Button::new(text))` diff --git a/egui/src/widgets/text_edit.rs b/egui/src/widgets/text_edit.rs index a8ce4c13..6236151a 100644 --- a/egui/src/widgets/text_edit.rs +++ b/egui/src/widgets/text_edit.rs @@ -108,12 +108,6 @@ impl CCursorPair { } } -#[derive(Clone, Copy, Debug, Default)] -#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] -pub struct CodingConfig { - pub tab_moves_focus: bool, -} - /// A text region that the user can edit the contents of. /// /// See also [`Ui::text_edit_singleline`] and [`Ui::text_edit_multiline`]. @@ -146,7 +140,7 @@ pub struct TextEdit<'t> { enabled: bool, desired_width: Option, desired_height_rows: usize, - tab_moves_focus: bool, + lock_focus: bool, } impl<'t> TextEdit<'t> { pub fn cursor(ui: &Ui, id: Id) -> Option { @@ -178,7 +172,7 @@ impl<'t> TextEdit<'t> { enabled: true, desired_width: None, desired_height_rows: 1, - tab_moves_focus: true, + lock_focus: true, } } @@ -197,37 +191,19 @@ impl<'t> TextEdit<'t> { enabled: true, desired_width: None, desired_height_rows: 4, - tab_moves_focus: true, + lock_focus: true, } } - /// When this is true, then pass focus to the next - /// widget. - pub fn tab_moves_focus(mut self, b: bool) -> Self { - self.tab_moves_focus = b; - self - } - /// Build a `TextEdit` focused on code editing. /// By default it comes with: /// - monospaced font /// - focus lock pub fn code_editor(self) -> Self { - self.text_style(TextStyle::Monospace).tab_moves_focus(false) - } - - /// Build a `TextEdit` focused on code editing with configurable `Tab` management. - /// - /// Shortcut for: - /// ```rust, ignore - /// egui::TextEdit::multiline(code_snippet) - /// .code_editor() - /// .tab_moves_focus(tab_moves_focus); - /// ``` - pub fn code_editor_with_config(self, config: CodingConfig) -> Self { - self.code_editor().tab_moves_focus(config.tab_moves_focus) + self.text_style(TextStyle::Monospace).lock_focus(true) } + /// Use if you want to set an explicit `Id` for this widget. pub fn id(mut self, id: Id) -> Self { self.id = Some(id); self @@ -292,6 +268,16 @@ impl<'t> TextEdit<'t> { self.desired_height_rows = desired_height_rows; self } + + /// When `false` (default), pressing TAB will move focus + /// to the next widget. + /// + /// When `true`, the widget will keep the focus and pressing TAB + /// will insert the `'\t'` character. + pub fn lock_focus(mut self, b: bool) -> Self { + self.lock_focus = b; + self + } } impl<'t> Widget for TextEdit<'t> { @@ -348,7 +334,7 @@ impl<'t> TextEdit<'t> { enabled, desired_width, desired_height_rows, - tab_moves_focus, + lock_focus, } = self; let text_style = text_style.unwrap_or_else(|| ui.style().body_text_style); @@ -454,7 +440,7 @@ impl<'t> TextEdit<'t> { let mut text_cursor = None; if ui.memory().has_focus(id) && enabled { - ui.memory().lock_focus(id, !tab_moves_focus); + ui.memory().lock_focus(id, lock_focus); let mut cursorp = state .cursorp diff --git a/egui_demo_lib/src/apps/demo/widgets.rs b/egui_demo_lib/src/apps/demo/widgets.rs index 244b142c..c4437e25 100644 --- a/egui_demo_lib/src/apps/demo/widgets.rs +++ b/egui_demo_lib/src/apps/demo/widgets.rs @@ -22,10 +22,9 @@ pub struct Widgets { radio: Enum, angle: f32, color: Color32, - show_password: bool, single_line_text_input: String, multiline_text_input: String, - tab_moves_focus: bool, + lock_focus: bool, code_snippet: String, } @@ -38,31 +37,14 @@ impl Default for Widgets { angle: std::f32::consts::TAU / 3.0, color: (Rgba::from_rgb(0.0, 1.0, 0.5) * 0.75).into(), single_line_text_input: "Hello World!".to_owned(), - show_password: false, - tab_moves_focus: false, + lock_focus: true, multiline_text_input: "Text can both be so wide that it needs a line break, but you can also add manual line break by pressing enter, creating new paragraphs.\nThis is the start of the next paragraph.\n\nClick me to edit me!".to_owned(), - code_snippet: r#"// Full identation blocks - // Spaces Spaces Spaces - // Tab Tab Tab - // Spaces Tab Spaces - // Tab Spaces Tab - -// Partial identation blocks - // Space Tab - // Space Space Tab - // Space Space Space Tab - // Space / / Space - // Space Space / / - // Space Space Space / - -// Use the configs above to play with the tab management -// Also existing tabs are kept as tabs. - + code_snippet: "\ fn main() { - println!("Hello world!"); +\tprintln!(\"Hello world!\"); } -"#.to_owned(), +".to_owned(), } } } @@ -183,14 +165,16 @@ impl Widgets { ui.separator(); - ui.checkbox(&mut self.tab_moves_focus, "Tabs moves focus"); + ui.checkbox(&mut self.lock_focus, "Lock focus") + .on_hover_text( + "When checked, pressing TAB will insert a tab instead of moving focus", + ); }); - ui.code_editor_with_config( - &mut self.code_snippet, - CodingConfig { - tab_moves_focus: self.tab_moves_focus, - }, + ui.add( + TextEdit::multiline(&mut self.code_snippet) + .code_editor() + .lock_focus(self.lock_focus), ); } } diff --git a/epaint/src/text/font.rs b/epaint/src/text/font.rs index c55b2493..1ee359aa 100644 --- a/epaint/src/text/font.rs +++ b/epaint/src/text/font.rs @@ -120,7 +120,7 @@ impl FontImpl { if c == '\t' { if let Some(space) = self.glyph_info(' ') { - glyph_info.advance_width = crate::text::MAX_TAB_SIZE * space.advance_width; + glyph_info.advance_width = crate::text::TAB_SIZE * space.advance_width; } } diff --git a/epaint/src/text/mod.rs b/epaint/src/text/mod.rs index fbd6eb6b..6f56ac2d 100644 --- a/epaint/src/text/mod.rs +++ b/epaint/src/text/mod.rs @@ -6,7 +6,7 @@ mod fonts; mod galley; /// Default size for a `\t` character. -pub const MAX_TAB_SIZE: f32 = 4.0; +pub const TAB_SIZE: f32 = 4.0; pub use { fonts::{FontDefinitions, FontFamily, Fonts, TextStyle},