|
|
|
@ -1,4 +1,5 @@
@@ -1,4 +1,5 @@
|
|
|
|
|
use eframe::egui; |
|
|
|
|
use egui::{ScrollArea, TextEdit}; |
|
|
|
|
use serde_json::{Value, to_string_pretty}; |
|
|
|
|
use std::path::{Path, PathBuf}; |
|
|
|
|
use walkdir::WalkDir; |
|
|
|
@ -8,97 +9,63 @@ pub struct TextEditorApp {
@@ -8,97 +9,63 @@ pub struct TextEditorApp {
|
|
|
|
|
files: Vec<PathBuf>, |
|
|
|
|
selected_file: Option<PathBuf>, |
|
|
|
|
file_content: String, |
|
|
|
|
pending_selection: Option<PathBuf>, // 新增字段用于延迟加载
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Default for TextEditorApp { |
|
|
|
|
fn default() -> Self { |
|
|
|
|
Self { |
|
|
|
|
current_dir: String::from("C:\\"), // 默认目录
|
|
|
|
|
current_dir: String::from("C:\\"), |
|
|
|
|
files: Vec::new(), |
|
|
|
|
selected_file: None, |
|
|
|
|
file_content: String::new(), |
|
|
|
|
pending_selection: None, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl eframe::App for TextEditorApp { |
|
|
|
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { |
|
|
|
|
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { |
|
|
|
|
ui.heading("轻量文本编辑器"); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
egui::CentralPanel::default().show(ctx, |ui| { |
|
|
|
|
ui.horizontal(|ui| { |
|
|
|
|
// 左侧资源管理器面板
|
|
|
|
|
egui::SidePanel::left("explorer_panel") |
|
|
|
|
.resizable(true) |
|
|
|
|
.default_width(200.0) |
|
|
|
|
.show_inside(ui, |ui| { |
|
|
|
|
ui.heading("资源管理器"); |
|
|
|
|
|
|
|
|
|
// 目录输入框
|
|
|
|
|
ui.horizontal(|ui| { |
|
|
|
|
ui.label("目录:"); |
|
|
|
|
ui.text_edit_singleline(&mut self.current_dir); |
|
|
|
|
if ui.button("加载").clicked() { |
|
|
|
|
self.load_directory(); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// 文件列表
|
|
|
|
|
egui::ScrollArea::vertical().show(ui, |ui| { |
|
|
|
|
let mut clicked_file = None; |
|
|
|
|
|
|
|
|
|
for file in &self.files { |
|
|
|
|
let display_name = file |
|
|
|
|
.file_name() |
|
|
|
|
.and_then(|n| n.to_str()) |
|
|
|
|
.unwrap_or_default(); |
|
|
|
|
|
|
|
|
|
if ui |
|
|
|
|
.selectable_label( |
|
|
|
|
self.selected_file.as_ref() == Some(file), |
|
|
|
|
display_name, |
|
|
|
|
) |
|
|
|
|
.clicked() |
|
|
|
|
{ |
|
|
|
|
clicked_file = Some(file.clone()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let Some(file) = clicked_file { |
|
|
|
|
self.selected_file = Some(file.clone()); |
|
|
|
|
self.load_file_content(&file); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// 右侧文本编辑面板
|
|
|
|
|
egui::CentralPanel::default().show_inside(ui, |ui| { |
|
|
|
|
ui.heading("文本编辑器"); |
|
|
|
|
|
|
|
|
|
// 文本编辑区域
|
|
|
|
|
egui::ScrollArea::both().show(ui, |ui| { |
|
|
|
|
ui.text_edit_multiline(&mut self.file_content); |
|
|
|
|
}); |
|
|
|
|
// 先处理待处理的文件选择
|
|
|
|
|
if let Some(file_path) = self.pending_selection.take() { |
|
|
|
|
self.selected_file = Some(file_path.clone()); |
|
|
|
|
self.load_file_content(&file_path); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 转换按钮
|
|
|
|
|
ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { |
|
|
|
|
ui.horizontal(|ui| { |
|
|
|
|
if ui.button("转换为大写").clicked() { |
|
|
|
|
self.convert_to_uppercase(); |
|
|
|
|
} |
|
|
|
|
if ui.button("转换为小写").clicked() { |
|
|
|
|
self.convert_to_lowercase(); |
|
|
|
|
} |
|
|
|
|
if ui.button("格式化JSON").clicked() { |
|
|
|
|
self.format_json(); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
let available_height = ctx.available_rect().height() - 40.0; |
|
|
|
|
|
|
|
|
|
egui::SidePanel::left("resource_panel") |
|
|
|
|
.resizable(false) |
|
|
|
|
.default_width(200.0) |
|
|
|
|
.show(ctx, |ui| { |
|
|
|
|
ui.set_height(available_height); |
|
|
|
|
ScrollArea::vertical().show(ui, |ui| { |
|
|
|
|
ui.label("项目文件"); |
|
|
|
|
ui.separator(); |
|
|
|
|
|
|
|
|
|
// 保存文件列表到临时变量避免借用冲突
|
|
|
|
|
let files = self.files.clone(); |
|
|
|
|
for file in files { |
|
|
|
|
if ui.selectable_label( |
|
|
|
|
self.selected_file.as_ref() == Some(&file), |
|
|
|
|
file.file_name().unwrap().to_string_lossy() |
|
|
|
|
).clicked() { |
|
|
|
|
// 不直接调用load方法,而是设置待处理选择
|
|
|
|
|
self.pending_selection = Some(file); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
egui::CentralPanel::default() |
|
|
|
|
.frame(egui::Frame::NONE) |
|
|
|
|
.show(ctx, |ui| { |
|
|
|
|
TextEdit::multiline(&mut self.file_content) |
|
|
|
|
.desired_width(f32::INFINITY) |
|
|
|
|
.desired_rows((available_height / 20.0) as usize) |
|
|
|
|
.font(egui::TextStyle::Monospace) |
|
|
|
|
.show(ui); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -142,7 +109,6 @@ impl TextEditorApp {
@@ -142,7 +109,6 @@ impl TextEditorApp {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Err(e) => { |
|
|
|
|
// 可以在这里添加错误处理,比如显示错误消息
|
|
|
|
|
println!("JSON 格式化错误: {}", e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|