ced/src/ui/central_panel.rs

219 lines
8.9 KiB
Rust
Raw Normal View History

2025-07-05 14:42:45 -04:00
mod editor;
mod find_highlight;
mod line_numbers;
use crate::app::TextEditor;
use eframe::egui;
use egui::UiKind;
2025-07-05 14:42:45 -04:00
use self::editor::editor_view_ui;
use self::line_numbers::{get_visual_line_mapping, render_line_numbers};
pub(crate) fn central_panel(app: &mut TextEditor, ctx: &egui::Context) {
let show_line_numbers = app.show_line_numbers;
let word_wrap = app.word_wrap;
let line_side = app.line_side;
let font_size = app.font_size;
let _output = egui::CentralPanel::default()
2025-07-05 14:42:45 -04:00
.frame(egui::Frame::NONE)
.show(ctx, |ui| {
let bg_color = ui.visuals().extreme_bg_color;
let panel_rect = ui.available_rect_before_wrap();
ui.painter().rect_filled(panel_rect, 0.0, bg_color);
let editor_height = panel_rect.height();
if !show_line_numbers || app.get_active_tab().is_none() {
let _scroll_response =
egui::ScrollArea::vertical()
.auto_shrink([false; 2])
.show(ui, |ui| {
let full_rect = ui.available_rect_before_wrap();
let context_response =
ui.allocate_response(full_rect.size(), egui::Sense::click());
ui.scope_builder(egui::UiBuilder::new().max_rect(full_rect), |ui| {
editor_view_ui(ui, app);
});
handle_empty(ui, app, &context_response);
});
2025-07-05 14:42:45 -04:00
return;
}
let line_count = app.get_text_processing_result().line_count;
let editor_dimensions = app.calculate_editor_dimensions(ui);
let line_number_width = editor_dimensions.line_number_width;
let visual_line_mapping = if word_wrap {
let available_text_width = editor_dimensions.text_width;
if let Some(active_tab) = app.get_active_tab() {
get_visual_line_mapping(
ui,
&active_tab.content,
available_text_width,
font_size,
)
} else {
vec![]
}
} else {
vec![]
};
let line_numbers_widget = |ui: &mut egui::Ui| {
render_line_numbers(
ui,
line_count,
&visual_line_mapping,
line_number_width,
word_wrap,
font_size,
);
};
let separator_widget = |ui: &mut egui::Ui| {
ui.add_space(3.0);
let separator_x = ui.cursor().left();
let mut y_range = ui.available_rect_before_wrap().y_range();
y_range.max += 2.0 * font_size;
2025-07-05 14:42:45 -04:00
ui.painter()
.vline(separator_x, y_range, ui.visuals().window_stroke);
ui.add_space(4.0);
};
egui::ScrollArea::vertical()
.auto_shrink([false; 2])
.show(ui, |ui| {
if line_side {
let text_editor_width =
editor_dimensions.text_width + editor_dimensions.total_reserved_width;
2025-07-05 14:42:45 -04:00
ui.allocate_ui_with_layout(
egui::vec2(text_editor_width, editor_height),
egui::Layout::left_to_right(egui::Align::TOP),
|ui| {
ui.allocate_ui_with_layout(
egui::vec2(editor_dimensions.text_width, editor_height),
egui::Layout::left_to_right(egui::Align::TOP),
|ui| {
let full_rect = ui.available_rect_before_wrap();
let context_response = ui.allocate_response(
full_rect.size(),
egui::Sense::click(),
);
ui.scope_builder(
egui::UiBuilder::new().max_rect(full_rect),
|ui| {
editor_view_ui(ui, app);
},
);
handle_empty(ui, app, &context_response);
2025-07-05 14:42:45 -04:00
},
);
separator_widget(ui);
line_numbers_widget(ui);
},
);
} else {
let text_editor_width =
editor_dimensions.text_width + editor_dimensions.total_reserved_width;
2025-07-05 14:42:45 -04:00
ui.allocate_ui_with_layout(
egui::vec2(text_editor_width, editor_height),
egui::Layout::left_to_right(egui::Align::TOP),
|ui| {
line_numbers_widget(ui);
separator_widget(ui);
let editor_area = ui.available_rect_before_wrap();
let context_response =
ui.allocate_response(editor_area.size(), egui::Sense::click());
ui.scope_builder(
egui::UiBuilder::new().max_rect(editor_area),
|ui| {
editor_view_ui(ui, app);
},
);
handle_empty(ui, app, &context_response);
2025-07-05 14:42:45 -04:00
},
);
}
});
});
}
2025-07-15 00:42:01 -04:00
fn handle_empty(_ui: &mut egui::Ui, app: &mut TextEditor, context_response: &egui::Response) {
if context_response.clicked() {
let text_edit_id = egui::Id::new("main_text_editor");
if let Some(mut state) = egui::TextEdit::load_state(_ui.ctx(), text_edit_id) {
if let Some(active_tab) = app.get_active_tab() {
let text_len = active_tab.content.len();
let cursor_pos = egui::text::CCursor::new(text_len);
state
.cursor
.set_char_range(Some(egui::text::CCursorRange::one(cursor_pos)));
egui::TextEdit::store_state(_ui.ctx(), text_edit_id, state);
_ui.ctx().memory_mut(|mem| {
mem.request_focus(text_edit_id);
});
}
}
}
context_response.context_menu(|ui| {
2025-07-15 00:42:01 -04:00
let text_len = app.get_active_tab().unwrap().content.len();
let reset_zoom_key = egui::Id::new("editor_reset_zoom");
if ui.button("Cut").clicked() {
ui.ctx()
.send_viewport_cmd(egui::ViewportCommand::RequestCut);
ui.close_kind(UiKind::Menu);
2025-07-15 00:42:01 -04:00
}
if ui.button("Copy").clicked() {
ui.ctx()
.send_viewport_cmd(egui::ViewportCommand::RequestCopy);
ui.close_kind(UiKind::Menu);
2025-07-15 00:42:01 -04:00
}
if ui.button("Paste").clicked() {
ui.ctx()
.send_viewport_cmd(egui::ViewportCommand::RequestPaste);
ui.close_kind(UiKind::Menu);
2025-07-15 00:42:01 -04:00
}
if ui.button("Delete").clicked() {
ui.ctx().input_mut(|i| {
i.events.push(egui::Event::Key {
key: egui::Key::Delete,
physical_key: None,
pressed: true,
repeat: false,
modifiers: egui::Modifiers::NONE,
})
});
ui.close_kind(UiKind::Menu);
2025-07-15 00:42:01 -04:00
}
if ui.button("Select All").clicked() {
let text_edit_id = egui::Id::new("main_text_editor");
if let Some(mut state) = egui::TextEdit::load_state(ui.ctx(), text_edit_id) {
let select_all_range = egui::text::CCursorRange::two(
egui::text::CCursor::new(0),
egui::text::CCursor::new(text_len),
);
state.cursor.set_char_range(Some(select_all_range));
egui::TextEdit::store_state(ui.ctx(), text_edit_id, state);
}
ui.close_kind(UiKind::Menu);
2025-07-15 00:42:01 -04:00
}
ui.separator();
if ui.button("Reset Zoom").clicked() {
ui.ctx().memory_mut(|mem| {
mem.data.insert_temp(reset_zoom_key, true);
});
ui.close_kind(UiKind::Menu);
2025-07-15 00:42:01 -04:00
}
});
2025-07-05 14:42:45 -04:00
}