diff --git a/Cargo.lock b/Cargo.lock index aa5cddd..7997fc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,7 +815,7 @@ dependencies = [ [[package]] name = "editors" -version = "0.0.6" +version = "0.1.0" dependencies = [ "eframe", "egui", @@ -926,7 +926,7 @@ dependencies = [ [[package]] name = "enc_dec" -version = "0.0.6" +version = "0.1.0" [[package]] name = "encoding_rs" @@ -1630,7 +1630,7 @@ dependencies = [ [[package]] name = "manager" -version = "0.0.6" +version = "0.1.0" dependencies = [ "eframe", "egui", @@ -1973,7 +1973,7 @@ dependencies = [ [[package]] name = "packets" -version = "0.0.6" +version = "0.1.0" dependencies = [ "encoding_rs", ] @@ -2352,7 +2352,7 @@ dependencies = [ [[package]] name = "server" -version = "0.0.6" +version = "0.1.0" dependencies = [ "enc_dec", "packets", @@ -2440,7 +2440,7 @@ dependencies = [ [[package]] name = "sniffer" -version = "0.0.6" +version = "0.1.0" dependencies = [ "eframe", "egui", diff --git a/Cargo.toml b/Cargo.toml index c56ff1e..06b19bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.0.6" +version = "0.1.0" description = "W2.Rust is a set of tools and GameServer made using the Rust language." readme = "README.md" repository = "https://github.com/Rechdan/W2.Rust" diff --git a/apps/editors/src/editors/mod.rs b/apps/editors/src/editors/mod.rs index a1bd2f4..4f97cfe 100644 --- a/apps/editors/src/editors/mod.rs +++ b/apps/editors/src/editors/mod.rs @@ -1,115 +1,13 @@ -use egui::{Button, Ui}; -use egui_extras::{Size, StripBuilder}; -use rfd::FileDialog; -use std::{path::PathBuf, sync::Mutex}; - -use self::server_list::ServerListEditor; +use egui::Ui; +use std::path::PathBuf; pub mod server_list; +pub mod server_name; -#[derive(Default, Clone)] -enum EditorSelected { - #[default] - None, - ServerList(ServerListEditor), -} - -#[derive(Default)] -pub struct Editors { - folder_selected: Mutex>, - editor_selected: Mutex, +pub trait EditorRender { + fn name() -> &'static str; + fn new(folder: PathBuf) -> Option>; + fn render(&mut self, ui: &mut Ui); } -impl Editors { - pub fn render(&self, ui: &mut Ui) { - let folder_selected = self.folder_selected.lock().unwrap().clone(); - - match folder_selected.clone() { - Some(folder) => { - self.render_selected_folder(ui, folder.clone()); - self.render_body(ui, folder.clone()); - } - - None => { - if ui.button("Selecionar pasta do cliente").clicked() { - self.pick_new_folder(); - } - } - }; - } - - fn pick_new_folder(&self) { - match FileDialog::new().pick_folder() { - Some(new_folder) => { - *self.folder_selected.lock().unwrap() = Some(new_folder); - *self.editor_selected.lock().unwrap() = EditorSelected::None; - } - None => {} - }; - } - - fn render_selected_folder(&self, ui: &mut Ui, folder: PathBuf) { - ui.horizontal(|ui| { - ui.label("Pasta:"); - - if ui.link(folder.display().to_string()).clicked() { - self.pick_new_folder(); - } - }); - } - - fn render_body(&self, ui: &mut Ui, folder: PathBuf) { - StripBuilder::new(ui) - .size(Size::exact(200.0)) - .size(Size::remainder()) - .horizontal(|mut strip| { - strip.cell(|ui| { - ui.group(|ui| { - ui.set_min_size(ui.available_size()); - - self.render_editors_list(ui, folder.clone()); - }); - }); - - strip.cell(|ui| { - ui.group(|ui| { - ui.set_min_size(ui.available_size()); - - match self.editor_selected.lock().unwrap().clone() { - EditorSelected::None => { - ui.label("Selecione um editor ao lado"); - } - - EditorSelected::ServerList(server_list) => { - server_list.render(ui); - } - }; - }); - }); - }); - } - - fn render_editors_list(&self, ui: &mut Ui, folder: PathBuf) { - ui.vertical_centered_justified(|ui| { - self.render_server_list_editor_button(ui, folder); - }); - } - - fn render_server_list_editor_button(&self, ui: &mut Ui, folder: PathBuf) { - let mut editor_selected = self.editor_selected.lock().unwrap(); - - let selected = match *editor_selected { - EditorSelected::ServerList(_) => true, - _ => false, - }; - - let btn = ui.add(Button::new("Server List + SN").selected(selected)); - - if btn.clicked() && !selected { - match ServerListEditor::new(folder.clone()) { - Some(server_list) => *editor_selected = EditorSelected::ServerList(server_list), - None => {} - }; - } - } -} +pub struct Editor {} diff --git a/apps/editors/src/editors/server_list.rs b/apps/editors/src/editors/server_list.rs index 5127006..4ff7ae6 100644 --- a/apps/editors/src/editors/server_list.rs +++ b/apps/editors/src/editors/server_list.rs @@ -1,68 +1,47 @@ -use egui::{vec2, Align, Button, Layout, Ui}; -use egui_extras::{Size, StripBuilder}; +use egui::{Button, Ui}; use fixedstr::zstr; -use std::{ - path::PathBuf, - str::FromStr, - sync::{Arc, Mutex}, -}; +use std::{path::PathBuf, str::FromStr}; -use crate::structs::{ServerList, ServerName}; +use crate::structs::ServerList; + +use super::EditorRender; -#[derive(Clone)] pub struct ServerListEditor { - folder: Arc, - server_list: Arc>, - server_name: Arc>, - selected_world_index: Arc>, - buttons_height: Arc>, + folder: PathBuf, + server_list: ServerList, + selected_world_index: usize, } -impl ServerListEditor { - pub fn new(folder: PathBuf) -> Option { +impl EditorRender for ServerListEditor { + fn name() -> &'static str { + "Server List" + } + + fn new(folder: PathBuf) -> Option> { let server_list = match ServerList::new(folder.clone()) { Some(server_list) => server_list, None => return None, }; - let server_name = match ServerName::new(folder.clone()) { - Some(server_name) => server_name, - None => return None, - }; - - Some(Self { - folder: Arc::new(folder), - server_list: Arc::new(Mutex::new(server_list)), - server_name: Arc::new(Mutex::new(server_name)), - selected_world_index: Default::default(), - buttons_height: Default::default(), - }) + Some(Box::new(Self { + folder, + server_list, + selected_world_index: 0, + })) } - pub fn render(&self, ui: &mut Ui) { - StripBuilder::new(ui) - .size(Size::relative(0.5)) - .size(Size::remainder()) - .horizontal(|mut s| { - s.cell(|ui| { - ui.label("Server List"); - ui.separator(); - self.render_key_editor(ui); - self.render_world_selector(ui); - self.render_world_editor(ui); - self.footer_actions_render(ui); - }); - - s.cell(|ui| { - ui.label("Server Name (SN)"); - ui.separator(); - self.server_name_editor(ui); - }); - }); + fn render(&mut self, ui: &mut Ui) { + ui.set_width(240.0); + self.render_key_editor(ui); + self.render_world_selector(ui); + self.render_world_editor(ui); + self.footer_actions(ui); } +} - fn render_key_editor(&self, ui: &mut Ui) { - let mut server_list = self.server_list.lock().unwrap(); +impl ServerListEditor { + fn render_key_editor(&mut self, ui: &mut Ui) { + let server_list = &mut self.server_list; ui.vertical(|ui| { ui.label("Key:"); @@ -77,8 +56,8 @@ impl ServerListEditor { }); } - fn render_world_selector(&self, ui: &mut Ui) { - let mut selected_world_index = self.selected_world_index.lock().unwrap(); + fn render_world_selector(&mut self, ui: &mut Ui) { + let selected_world_index = &mut self.selected_world_index; ui.vertical(|ui| { ui.label("Mundo:"); @@ -98,9 +77,9 @@ impl ServerListEditor { }); } - fn render_world_editor(&self, ui: &mut Ui) { - let mut server_list = self.server_list.lock().unwrap(); - let selected_world_index = self.selected_world_index.lock().unwrap().clone(); + fn render_world_editor(&mut self, ui: &mut Ui) { + let server_list = &mut self.server_list; + let selected_world_index = self.selected_world_index; let (world_url, world_channels) = server_list.worlds.get_mut(selected_world_index).unwrap(); @@ -124,68 +103,11 @@ impl ServerListEditor { } } - fn server_name_editor(&self, ui: &mut Ui) { - let mut server_name = self.server_name.lock().unwrap(); - - StripBuilder::new(ui) - .size(Size::relative(0.5)) - .size(Size::remainder()) - .horizontal(|mut s| { - s.cell(|ui| { - for i in 0..10 { - let world_name = &mut server_name.worlds[i].clone(); - - ui.horizontal(|ui| { - let name = &mut world_name.to_string(); - if ui.text_edit_singleline(name).changed() { - server_name.worlds[i] = zstr::from(name); - } - }); - } - }); - - s.cell(|ui| { - for i in 0..10 { - let world_count = &mut server_name.counts[i][0].clone(); - - ui.horizontal(|ui| { - let count = &mut world_count.to_string(); - if ui.text_edit_singleline(count).changed() { - server_name.counts[i][0] = match FromStr::from_str(count) { - Ok(v) => v, - Err(_error) => world_count.clone(), - }; - } - }); - } - }); - }); - } - - fn footer_actions_render(&self, ui: &mut Ui) { - let folder = (*self.folder).clone(); - let server_list = self.server_list.lock().unwrap(); - let server_name = self.server_name.lock().unwrap(); - let mut buttons_height = self.buttons_height.lock().unwrap(); - - let min_size = vec2( - ui.available_width(), - ui.available_height().max(*buttons_height), - ); - - ui.allocate_ui_with_layout(min_size.clone(), Layout::bottom_up(Align::Min), |ui| { - ui.set_min_size(min_size.clone()); - - *buttons_height = ui - .horizontal_wrapped(|ui| { - if ui.button("Salvar").clicked() { - server_list.save(folder.clone()); - server_name.save(folder.clone()); - } - }) - .response - .rect - .height(); + fn footer_actions(&mut self, ui: &mut Ui) { + ui.horizontal_wrapped(|ui| { + if ui.button("Salvar").clicked() { + self.server_list.save(self.folder.clone()); + } }); } } diff --git a/apps/editors/src/editors/server_name.rs b/apps/editors/src/editors/server_name.rs new file mode 100644 index 0000000..2c574e6 --- /dev/null +++ b/apps/editors/src/editors/server_name.rs @@ -0,0 +1,85 @@ +use egui::Ui; +use fixedstr::zstr; +use std::{path::PathBuf, str::FromStr}; + +use crate::structs::ServerName; + +use super::EditorRender; + +pub struct ServerNameEditor { + folder: PathBuf, + server_name: ServerName, +} + +impl EditorRender for ServerNameEditor { + fn name() -> &'static str { + "Server Name" + } + + fn new(folder: PathBuf) -> Option> { + let server_name = match ServerName::new(folder.clone()) { + Some(server_name) => server_name, + None => return None, + }; + + Some(Box::new(Self { + folder, + server_name, + })) + } + + fn render(&mut self, ui: &mut Ui) { + ui.set_width(240.0); + self.server_name_editor(ui); + self.footer_actions_render(ui); + } +} + +impl ServerNameEditor { + fn server_name_editor(&mut self, ui: &mut Ui) { + let server_name = &mut self.server_name; + + ui.horizontal(|ui| { + ui.vertical(|ui| { + ui.set_width(ui.available_width() / 2.0); + + ui.label("Nomes:"); + + for i in 0..10 { + let world_name = &mut server_name.worlds[i].clone(); + let name = &mut world_name.to_string(); + + if ui.text_edit_singleline(name).changed() { + server_name.worlds[i] = zstr::from(name); + } + } + }); + + ui.vertical(|ui| { + ui.set_width(ui.available_width()); + + ui.label("Ordem:"); + + for i in 0..10 { + let world_count = &mut server_name.counts[i][0].clone(); + let count = &mut world_count.to_string(); + + if ui.text_edit_singleline(count).changed() { + server_name.counts[i][0] = match FromStr::from_str(count) { + Ok(v) => v, + Err(_error) => world_count.clone(), + }; + } + } + }); + }); + } + + fn footer_actions_render(&mut self, ui: &mut Ui) { + ui.horizontal_wrapped(|ui| { + if ui.button("Salvar").clicked() { + self.server_name.save(self.folder.clone()); + } + }); + } +} diff --git a/apps/editors/src/main_window.rs b/apps/editors/src/main_window.rs index c13245c..88fa4d1 100644 --- a/apps/editors/src/main_window.rs +++ b/apps/editors/src/main_window.rs @@ -1,28 +1,101 @@ use eframe::{App, Frame}; -use egui::{CentralPanel, Context}; +use egui::{Button, CentralPanel, Context, SidePanel, TopBottomPanel, Ui, Window}; +use rfd::FileDialog; +use std::path::PathBuf; -use crate::editors::Editors; +use crate::editors::{server_list::ServerListEditor, server_name::ServerNameEditor, EditorRender}; +#[derive(Default)] pub struct MainWindow { - editors: Editors, + client_folder: Option, + + server_list: Option<(bool, Box)>, + server_name: Option<(bool, Box)>, } -impl Default for MainWindow { - fn default() -> Self { - Self { - editors: Default::default(), +impl App for MainWindow { + fn update(&mut self, ctx: &Context, _frame: &mut Frame) { + match self.client_folder.clone() { + Some(folder) => self.main_view(ctx, folder), + None => self.folder_picker(ctx), } } } -impl App for MainWindow { - fn update(&mut self, ctx: &Context, _frame: &mut Frame) { +impl MainWindow { + fn pick_new_folder(&mut self) { + match FileDialog::new().pick_folder() { + Some(new_folder) => { + self.client_folder = Some(new_folder); + } + None => {} + }; + } + + fn folder_picker(&mut self, ctx: &Context) { CentralPanel::default().show(ctx, |ui| { - ui.vertical(|ui| { - ui.heading("W2.Rust Editors"); + ui.heading("W2.Rust Editors"); - self.editors.render(ui); - }); + if ui.button("Selecionar pasta do cliente").clicked() { + self.pick_new_folder(); + } }); } + + fn main_view(&mut self, ctx: &Context, folder: PathBuf) { + TopBottomPanel::top("top_panel") + .resizable(false) + .exact_height(30.0) + .show(ctx, |ui| { + ui.horizontal_centered(|ui| { + ui.heading("W2.Rust Editors"); + }); + }); + + SidePanel::left("left_panel") + .resizable(false) + .exact_width(150.0) + .show(ctx, |ui| { + ui.vertical_centered_justified(|ui| { + Self::manage_editor_btn(&mut self.server_list, ui, folder.clone()); + Self::manage_editor_btn(&mut self.server_name, ui, folder.clone()); + }); + }); + + Self::manage_window(&mut self.server_list, ctx); + Self::manage_window(&mut self.server_name, ctx); + } + + fn manage_window(editor: &mut Option<(bool, Box)>, ctx: &Context) { + match editor { + Some((open, editor)) => { + Window::new(T::name()) + .resizable(false) + .open(open) + .show(ctx, |ui| { + editor.render(ui); + }); + } + None => {} + }; + } + + fn manage_editor_btn( + editor: &mut Option<(bool, Box)>, + ui: &mut Ui, + folder: PathBuf, + ) { + if ui + .add(Button::new(T::name()).selected(editor.as_ref().is_some_and(|(open, _)| *open))) + .clicked() + { + match editor { + Some((open, _)) => *open = !*open, + None => match T::new(folder) { + Some(new_editor) => *editor = Some((true, new_editor)), + None => {} + }, + }; + } + } }