From 90d3f54f13ff255e3bfbedd84d357085f7a34b5e Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:29:49 +1000 Subject: [PATCH 1/4] Semi-Working --- src/advanced_frame.rs | 80 +++++++++++++++++++++++++++++++++++ src/instance.rs | 14 ++++++ src/instances_frame_holder.rs | 39 +++++++++++++++++ src/main.rs | 36 ++++++++++++---- src/style.rs | 8 ++++ 5 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 src/advanced_frame.rs create mode 100644 src/instances_frame_holder.rs diff --git a/src/advanced_frame.rs b/src/advanced_frame.rs new file mode 100644 index 00000000..c354601b --- /dev/null +++ b/src/advanced_frame.rs @@ -0,0 +1,80 @@ +use iced::{Text, Element, Column, Button, button, Length, Alignment, alignment, Row, text_input, Padding}; + +use crate::{Message, instance::Instance, style}; + +#[derive(Debug)] +pub struct AdvancedFrame { + old_name: String, + instance: Option, + + close_button: button::State, + _name_input: text_input::State +} + +impl Default for AdvancedFrame { + fn default() -> Self { + Self { + old_name: String::default(), + instance: None, + close_button: button::State::default(), + _name_input: text_input::State::default() + } + } +} + +impl AdvancedFrame { + pub fn new(new_instance: Instance) -> Self{ + Self { + old_name: String::from(&new_instance.name), + instance: Some(new_instance), + ..Default::default() + } + } + + pub fn view(&mut self) -> Element { + + let close_button = Button::new(&mut self.close_button, style::close_icon()) + .style(style::Button::Icon) + .on_press(match &self.instance { + Some(inst) => Message::CloseAdvanced(self.old_name.clone(), inst.clone()), + None => Message::Dummy(()), + }); + + let mut p = Padding::new(0); + p.bottom = 60; + + let out = Column::new() + .push( + Row::new() + .width(Length::Fill) + .align_items(Alignment::End) + .push( + Text::new("Advanced Settings") + .size(26) + .horizontal_alignment(alignment::Horizontal::Center) + .width(Length::Fill), + ) + .push(close_button) + .padding(p) + ) + .padding(30) + .width(iced::Length::FillPortion(3)); + + if let Some(instance) = &self.instance { + out + .push( + { + let text = format!("Instance name: {}", &instance.name); + Text::new(text) + .size(18) + } + ) + .into() + } else { + out + .push(Text::new("How in the...")) + .into() + } + + } +} diff --git a/src/instance.rs b/src/instance.rs index 7fc4109f..23571cbb 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -57,6 +57,8 @@ pub struct Instance { #[serde(skip)] folder_button: button::State, #[serde(skip)] + advanced_button: button::State, + #[serde(skip)] delete_button: button::State, #[serde(skip)] @@ -149,6 +151,7 @@ pub enum InstanceMessage { Play(bool), Update, Folder, + Advanced, Delete, StateChanged(InstanceState), } @@ -175,6 +178,7 @@ impl Instance { play_button: button::State::default(), update_button: button::State::default(), folder_button: button::State::default(), + advanced_button: button::State::default(), delete_button: button::State::default(), } } @@ -225,6 +229,12 @@ impl Instance { InstanceMessage::Folder => { iced::Command::perform(open_folder(self.path.clone()), Message::Dummy) } + InstanceMessage::Advanced => { + let name = self.name.clone(); + iced::Command::perform(dummy(), move |_| { + Message::OpenAdvanced(name.clone()) + }) + } InstanceMessage::Delete => { let name = self.name.clone(); iced::Command::perform(delete(self.path.clone()), move |_| { @@ -249,6 +259,9 @@ impl Instance { let folder_button = Button::new(&mut self.folder_button, style::folder_icon()) .style(style::Button::Icon) .on_press(InstanceMessage::Folder); + let advanced_button = Button::new(&mut self.advanced_button, style::advanced_icon()) + .style(style::Button::Icon) + .on_press(InstanceMessage::Advanced); let mut delete_button = Button::new(&mut self.delete_button, style::delete_icon()) .style(style::Button::Destructive); @@ -317,6 +330,7 @@ impl Instance { .push(play_button) .push(update_button) .push(folder_button) + .push(advanced_button) .push(delete_button) } }) diff --git a/src/instances_frame_holder.rs b/src/instances_frame_holder.rs new file mode 100644 index 00000000..a58423c5 --- /dev/null +++ b/src/instances_frame_holder.rs @@ -0,0 +1,39 @@ +use iced::Element; + +use crate::advanced_frame; +use crate::instances_frame; +use crate::Message; + +#[derive(Debug)] +pub enum AdvancedFrameOpen { + Open(advanced_frame::AdvancedFrame), + Closed +} + +#[derive(Debug)] +pub struct InstanceFrameHolder { + pub instances_frame: instances_frame::InstancesFrame, + pub advanced_frame_open: AdvancedFrameOpen, +} + +impl Default for InstanceFrameHolder { + fn default() -> Self { + InstanceFrameHolder { + instances_frame: instances_frame::InstancesFrame::default(), + advanced_frame_open: AdvancedFrameOpen::Closed + } + } +} + +impl InstanceFrameHolder { + pub fn view(&mut self) -> Element { + match &mut self.advanced_frame_open { + AdvancedFrameOpen::Open(advanced_frame) => { + advanced_frame.view() + }, + AdvancedFrameOpen::Closed => { + self.instances_frame.view() + } + } + } +} diff --git a/src/main.rs b/src/main.rs index ecb6aa0a..dec773e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,10 +14,12 @@ use std::sync::mpsc::Sender; use std::thread; use std::time::Duration; +use advanced_frame::AdvancedFrame; use iced::{ alignment, button, scrollable, Alignment, Application, Button, Column, Command, Container, Element, Length, Row, Scrollable, Settings, Space, Subscription, Text, }; +use instances_frame_holder::AdvancedFrameOpen; use std::collections::VecDeque; use std::sync::Mutex; @@ -27,12 +29,14 @@ use crate::music::{MusicCommand, MusicState}; use crate::plugins_frame::PluginMessage; use lazy_static::lazy_static; +mod advanced_frame; mod archive; mod github; mod install; mod install_frame; mod instance; mod instances_frame; +mod instances_frame_holder; mod jenkins; mod logger; mod music; @@ -72,7 +76,7 @@ struct ESLauncher { music_button: button::State, music_state: MusicState, install_frame: install_frame::InstallFrame, - instances_frame: instances_frame::InstancesFrame, + instances_frame_holder: instances_frame_holder::InstanceFrameHolder, plugins_frame: plugins_frame::PluginsFrameState, log_scrollable: scrollable::State, message_receiver: MessageReceiver, @@ -95,6 +99,9 @@ pub enum Message { PluginMessage(String, PluginMessage), AddInstance(Instance), RemoveInstance(Option), + OpenAdvanced(String), + CloseAdvanced(String, Instance), + StrChanged(String), Dummy(()), MusicMessage(MusicCommand), ViewChanged(MainView), @@ -131,7 +138,7 @@ impl Application for ESLauncher { music_button: button::State::default(), music_state: MusicState::Playing, install_frame: install_frame::InstallFrame::default(), - instances_frame: instances_frame::InstancesFrame::default(), + instances_frame_holder: instances_frame_holder::InstanceFrameHolder::default(), plugins_frame: plugins_frame_state, log_scrollable: scrollable::State::default(), message_receiver: MessageReceiver {}, @@ -152,7 +159,7 @@ impl Application for ESLauncher { match message { Message::InstallFrameMessage(msg) => return self.install_frame.update(msg), Message::InstanceMessage(name, msg) => { - match self.instances_frame.instances.get_mut(&name) { + match self.instances_frame_holder.instances_frame.instances.get_mut(&name) { None => error!("Failed to find internal Instance with name {}", &name), Some(instance) => return instance.update(msg), } @@ -169,19 +176,31 @@ impl Application for ESLauncher { } Message::AddInstance(instance) => { let is_ready = instance.state.is_ready(); - self.instances_frame + self.instances_frame_holder + .instances_frame .instances .insert(instance.name.clone(), instance); if is_ready { - instance::perform_save_instances(self.instances_frame.instances.clone()) + instance::perform_save_instances(self.instances_frame_holder.instances_frame.instances.clone()) }; } Message::RemoveInstance(option) => { if let Some(name) = option { - self.instances_frame.instances.remove(&name); - instance::perform_save_instances(self.instances_frame.instances.clone()); + self.instances_frame_holder.instances_frame.instances.remove(&name); + instance::perform_save_instances(self.instances_frame_holder.instances_frame.instances.clone()); } } + Message::OpenAdvanced(instance_name) => { + if let Some(instance) = self.instances_frame_holder.instances_frame.instances.get(&instance_name) { + self.instances_frame_holder.advanced_frame_open = AdvancedFrameOpen::Open(AdvancedFrame::new(instance.clone())) + } + } + Message::CloseAdvanced(old_instance_name, new_instance) => { + self.instances_frame_holder.instances_frame.instances.remove(&old_instance_name); + self.instances_frame_holder.instances_frame.instances.insert(new_instance.name.clone(), new_instance); + instance::perform_save_instances(self.instances_frame_holder.instances_frame.instances.clone()); + self.instances_frame_holder.advanced_frame_open = AdvancedFrameOpen::Closed; + } Message::MusicMessage(cmd) => { self.music_sender.send(cmd).ok(); self.music_state = match cmd { @@ -195,6 +214,7 @@ impl Application for ESLauncher { } Message::Log(line) => self.log_buffer.push(line), Message::Dummy(_) => (), + _ => () } Command::none() } @@ -239,7 +259,7 @@ impl Application for ESLauncher { let main_view = match self.view { MainView::Instances => Container::new( Row::new() - .push(self.instances_frame.view()) + .push(self.instances_frame_holder.view()) .push(self.install_frame.view().map(Message::InstallFrameMessage)) .spacing(50), ), diff --git a/src/style.rs b/src/style.rs index b7b9b7f4..9d341a6a 100644 --- a/src/style.rs +++ b/src/style.rs @@ -43,6 +43,14 @@ pub fn folder_icon() -> Text { icon('\u{E930}') } +pub fn advanced_icon() -> Text { + icon('\u{E994}') +} + +pub fn close_icon() -> Text { + icon('\u{EA0F}') +} + pub enum Button { Icon, Destructive, From 89a08f4f57bb2fe22b4af49653d1bec11e07eeb1 Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Fri, 14 Apr 2023 12:12:13 +1000 Subject: [PATCH 2/4] Fixed --- src/advanced_frame.rs | 79 +++++++++++++++++++++++++++++++++++++------ src/install.rs | 1 + src/instance.rs | 13 ++++--- src/main.rs | 11 ++++-- 4 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/advanced_frame.rs b/src/advanced_frame.rs index c354601b..9daaedde 100644 --- a/src/advanced_frame.rs +++ b/src/advanced_frame.rs @@ -2,13 +2,20 @@ use iced::{Text, Element, Column, Button, button, Length, Alignment, alignment, use crate::{Message, instance::Instance, style}; +#[derive(Debug, Clone)] +pub enum AdvancedMessage { + NameTextInputChanged(String), + ArgsTextInputChanged(String), +} + #[derive(Debug)] pub struct AdvancedFrame { old_name: String, instance: Option, close_button: button::State, - _name_input: text_input::State + name_input: text_input::State, + args_input: text_input::State } impl Default for AdvancedFrame { @@ -17,7 +24,8 @@ impl Default for AdvancedFrame { old_name: String::default(), instance: None, close_button: button::State::default(), - _name_input: text_input::State::default() + name_input: text_input::State::default(), + args_input: text_input::State::default() } } } @@ -31,6 +39,18 @@ impl AdvancedFrame { } } + pub fn update(&mut self, message: AdvancedMessage) { + match message { + AdvancedMessage::NameTextInputChanged(string) => { + self.instance.as_mut().unwrap().name = string; + } + + AdvancedMessage::ArgsTextInputChanged(string) => { + self.instance.as_mut().unwrap().args = string; + } + } + } + pub fn view(&mut self) -> Element { let close_button = Button::new(&mut self.close_button, style::close_icon()) @@ -47,7 +67,7 @@ impl AdvancedFrame { .push( Row::new() .width(Length::Fill) - .align_items(Alignment::End) + .align_items(Alignment::End) .push( Text::new("Advanced Settings") .size(26) @@ -57,17 +77,47 @@ impl AdvancedFrame { .push(close_button) .padding(p) ) - .padding(30) - .width(iced::Length::FillPortion(3)); + .padding(40) + .width(iced::Length::FillPortion(3)) + .spacing(6); if let Some(instance) = &self.instance { + + let name_input = text_input::TextInput::new( + &mut self.name_input, + "Instance name", + &instance.name, + name_text_input_changed + ).padding(4); + + let out = out + .push( + Row::new() + .push( + { + let text = format!("Instance name:"); + Text::new(text) + .size(18) + } + ) + .push( + name_input + ) + .spacing(14) + .align_items(Alignment::Center) + ) + .push( + text_input::TextInput::new( + &mut self.args_input, + "Executable arguments", + &instance.args, + args_text_input_changed + ).padding(4) + ); + out .push( - { - let text = format!("Instance name: {}", &instance.name); - Text::new(text) - .size(18) - } + Text::new("-h or --help to log help") ) .into() } else { @@ -75,6 +125,13 @@ impl AdvancedFrame { .push(Text::new("How in the...")) .into() } - } } + +fn name_text_input_changed(string: String) -> Message { + Message::AdvancedMessage(AdvancedMessage::NameTextInputChanged(string)) +} + +fn args_text_input_changed(string: String) -> Message { + Message::AdvancedMessage(AdvancedMessage::ArgsTextInputChanged(string)) +} diff --git a/src/install.rs b/src/install.rs index 6c1430b6..fd92e870 100644 --- a/src/install.rs +++ b/src/install.rs @@ -93,6 +93,7 @@ pub fn install( Ok(Instance::new( destination, executable_path, + String::new(), name, version, instance_type, diff --git a/src/instance.rs b/src/instance.rs index 23571cbb..e9cae7d6 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -66,6 +66,7 @@ pub struct Instance { pub path: PathBuf, pub executable: PathBuf, + pub args: String, pub name: String, pub version: String, pub instance_type: InstanceType, @@ -160,6 +161,7 @@ impl Instance { pub fn new( path: PathBuf, executable: PathBuf, + args: String, name: String, version: String, instance_type: InstanceType, @@ -169,6 +171,7 @@ impl Instance { Self { path, executable, + args, name, version, instance_type, @@ -202,6 +205,7 @@ impl Instance { self.executable.clone(), self.name.clone(), do_debug, + self.args.clone() ), move |()| { Message::InstanceMessage( @@ -349,6 +353,7 @@ pub async fn perform_install( send_message(Message::AddInstance(Instance::new( path.clone(), "provisional".into(), + String::new(), name.clone(), instance_source.identifier.clone(), instance_type, @@ -397,15 +402,15 @@ pub async fn perform_update(instance: Instance) { } } -pub async fn perform_play(path: PathBuf, executable: PathBuf, name: String, do_debug: bool) { +pub async fn perform_play(path: PathBuf, executable: PathBuf, name: String, do_debug: bool, args: String) { send_message(Message::MusicMessage(MusicCommand::Pause)); - if let Err(e) = play(path, executable, name, do_debug).await { + if let Err(e) = play(path, executable, name, do_debug, args).await { error!("Failed to run game: {:#}", e); } send_message(Message::MusicMessage(MusicCommand::Play)); } -pub async fn play(path: PathBuf, executable: PathBuf, name: String, do_debug: bool) -> Result<()> { +pub async fn play(path: PathBuf, executable: PathBuf, name: String, do_debug: bool, args: String) -> Result<()> { let mut log_path = path; log_path.push("logs"); fs::create_dir_all(&log_path)?; @@ -431,7 +436,7 @@ pub async fn play(path: PathBuf, executable: PathBuf, name: String, do_debug: bo let output = if do_debug { cmd.arg("-d").output() } else { - cmd.output() + cmd.arg(args).output() }; match output { Ok(output) => { diff --git a/src/main.rs b/src/main.rs index dec773e6..bd841192 100644 --- a/src/main.rs +++ b/src/main.rs @@ -101,7 +101,7 @@ pub enum Message { RemoveInstance(Option), OpenAdvanced(String), CloseAdvanced(String, Instance), - StrChanged(String), + AdvancedMessage(advanced_frame::AdvancedMessage), Dummy(()), MusicMessage(MusicCommand), ViewChanged(MainView), @@ -201,6 +201,14 @@ impl Application for ESLauncher { instance::perform_save_instances(self.instances_frame_holder.instances_frame.instances.clone()); self.instances_frame_holder.advanced_frame_open = AdvancedFrameOpen::Closed; } + Message::AdvancedMessage(msg) => { + match &mut self.instances_frame_holder.advanced_frame_open { + AdvancedFrameOpen::Open(frame) => { + frame.update(msg); + } + AdvancedFrameOpen::Closed => {} + } + } Message::MusicMessage(cmd) => { self.music_sender.send(cmd).ok(); self.music_state = match cmd { @@ -214,7 +222,6 @@ impl Application for ESLauncher { } Message::Log(line) => self.log_buffer.push(line), Message::Dummy(_) => (), - _ => () } Command::none() } From 6f3ef32f439773fe44a2df253ca1156f3ce736ba Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Fri, 14 Apr 2023 12:16:22 +1000 Subject: [PATCH 3/4] Update instance.rs --- src/instance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/instance.rs b/src/instance.rs index e9cae7d6..51dfc57f 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -434,7 +434,7 @@ pub async fn play(path: PathBuf, executable: PathBuf, name: String, do_debug: bo let mut cmd = Command::new(&executable); let output = if do_debug { - cmd.arg("-d").output() + cmd.args(["-d", &args]).output() } else { cmd.arg(args).output() }; From 9faf1d3f492372aaafe519dd44484f3877bd6c84 Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Fri, 14 Apr 2023 12:24:46 +1000 Subject: [PATCH 4/4] Update advanced_frame.rs --- src/advanced_frame.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advanced_frame.rs b/src/advanced_frame.rs index 9daaedde..4a44edf7 100644 --- a/src/advanced_frame.rs +++ b/src/advanced_frame.rs @@ -31,7 +31,7 @@ impl Default for AdvancedFrame { } impl AdvancedFrame { - pub fn new(new_instance: Instance) -> Self{ + pub fn new(new_instance: Instance) -> Self { Self { old_name: String::from(&new_instance.name), instance: Some(new_instance),