diff --git a/assets/images/icons/applications-games-symbolic.svg b/assets/images/icons/applications-games-symbolic.svg
new file mode 100644
index 0000000..121a8ee
--- /dev/null
+++ b/assets/images/icons/applications-games-symbolic.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/assets/images/icons/applications-graphics-symbolic.svg b/assets/images/icons/applications-graphics-symbolic.svg
new file mode 100644
index 0000000..e47dfa3
--- /dev/null
+++ b/assets/images/icons/applications-graphics-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/dialog-information-symbolic.svg b/assets/images/icons/dialog-information-symbolic.svg
new file mode 100644
index 0000000..c948d27
--- /dev/null
+++ b/assets/images/icons/dialog-information-symbolic.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/assets/images/icons/document-properties-symbolic.svg b/assets/images/icons/document-properties-symbolic.svg
new file mode 100644
index 0000000..365c303
--- /dev/null
+++ b/assets/images/icons/document-properties-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/document-save-symbolic.svg b/assets/images/icons/document-save-symbolic.svg
new file mode 100644
index 0000000..9c5584d
--- /dev/null
+++ b/assets/images/icons/document-save-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/emblem-ok-symbolic.svg b/assets/images/icons/emblem-ok-symbolic.svg
new file mode 100644
index 0000000..7a9551f
--- /dev/null
+++ b/assets/images/icons/emblem-ok-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/emblem-system-symbolic.svg b/assets/images/icons/emblem-system-symbolic.svg
new file mode 100644
index 0000000..c01314d
--- /dev/null
+++ b/assets/images/icons/emblem-system-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/folder-symbolic.svg b/assets/images/icons/folder-symbolic.svg
new file mode 100644
index 0000000..9ab3c04
--- /dev/null
+++ b/assets/images/icons/folder-symbolic.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/assets/images/icons/go-next-symbolic.svg b/assets/images/icons/go-next-symbolic.svg
new file mode 100644
index 0000000..0ff48be
--- /dev/null
+++ b/assets/images/icons/go-next-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/go-previous-symbolic.svg b/assets/images/icons/go-previous-symbolic.svg
new file mode 100644
index 0000000..1b7901f
--- /dev/null
+++ b/assets/images/icons/go-previous-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/list-add-symbolic.svg b/assets/images/icons/list-add-symbolic.svg
new file mode 100644
index 0000000..cf68622
--- /dev/null
+++ b/assets/images/icons/list-add-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/media-playback-start-symbolic.svg b/assets/images/icons/media-playback-start-symbolic.svg
new file mode 100644
index 0000000..4dcac1b
--- /dev/null
+++ b/assets/images/icons/media-playback-start-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/open-menu-symbolic.svg b/assets/images/icons/open-menu-symbolic.svg
new file mode 100644
index 0000000..7f44743
--- /dev/null
+++ b/assets/images/icons/open-menu-symbolic.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/assets/images/icons/security-high-symbolic.svg b/assets/images/icons/security-high-symbolic.svg
new file mode 100644
index 0000000..b1f6447
--- /dev/null
+++ b/assets/images/icons/security-high-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/user-trash-symbolic.svg b/assets/images/icons/user-trash-symbolic.svg
new file mode 100644
index 0000000..b6f8bd1
--- /dev/null
+++ b/assets/images/icons/user-trash-symbolic.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/assets/images/icons/view-refresh-symbolic.svg b/assets/images/icons/view-refresh-symbolic.svg
new file mode 100644
index 0000000..3248fe7
--- /dev/null
+++ b/assets/images/icons/view-refresh-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/images/icons/violence-symbolic.svg b/assets/images/icons/violence-symbolic.svg
new file mode 100644
index 0000000..aa74bdc
--- /dev/null
+++ b/assets/images/icons/violence-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/assets/images/icons/window-close-symbolic.svg b/assets/images/icons/window-close-symbolic.svg
new file mode 100644
index 0000000..f68a861
--- /dev/null
+++ b/assets/images/icons/window-close-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/assets/resources.xml b/assets/resources.xml
index 1ac85ed..362d796 100644
--- a/assets/resources.xml
+++ b/assets/resources.xml
@@ -1,12 +1,37 @@
-
- images/icon.png
+
+ images/modern.svg
+ images/classic.svg
-
- images/modern.svg
+
+
+ images/icon.png
-
- images/classic.svg
+
+
+
+
+ images/icons/document-save-symbolic.svg
+ images/icons/folder-symbolic.svg
+ images/icons/emblem-ok-symbolic.svg
+ images/icons/open-menu-symbolic.svg
+ images/icons/media-playback-start-symbolic.svg
+ images/icons/window-close-symbolic.svg
+ images/icons/security-high-symbolic.svg
+ images/icons/emblem-system-symbolic.svg
+ images/icons/user-trash-symbolic.svg
+ images/icons/go-previous-symbolic.svg
+ images/icons/document-properties-symbolic.svg
+ images/icons/list-add-symbolic.svg
+ images/icons/view-refresh-symbolic.svg
+ images/icons/applications-games-symbolic.svg
+ images/icons/applications-graphics-symbolic.svg
+ images/icons/go-next-symbolic.svg
+ images/icons/dialog-information-symbolic.svg
+
+
+
+ images/icons/violence-symbolic.svg
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index a80b2ed..3a2fd56 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -24,6 +24,8 @@ use ui::main::*;
use ui::first_run::main::*;
pub const APP_ID: &str = "moe.launcher.an-anime-game-launcher";
+pub const APP_RESOURCE_PATH: &str = "/moe/launcher/an-anime-game-launcher";
+
pub const APP_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const APP_DEBUG: bool = cfg!(debug_assertions);
@@ -134,6 +136,10 @@ fn main() {
gtk::gio::resources_register_include!("resources.gresource")
.expect("Failed to register resources");
+ // Set icons search path
+ gtk::IconTheme::for_display(>k::gdk::Display::default().unwrap())
+ .add_resource_path(&format!("{APP_RESOURCE_PATH}/icons"));
+
// Set application's title
gtk::glib::set_application_name("An Anime Game Launcher");
gtk::glib::set_program_name(Some("An Anime Game Launcher"));
diff --git a/src/ui/first_run/welcome.rs b/src/ui/first_run/welcome.rs
index fab8d5c..a465cbb 100644
--- a/src/ui/first_run/welcome.rs
+++ b/src/ui/first_run/welcome.rs
@@ -29,7 +29,7 @@ impl SimpleAsyncComponent for WelcomeApp {
set_vexpand: true,
gtk::Image {
- set_resource: Some("/org/app/images/icon.png"),
+ set_icon_name: Some(APP_ID),
set_height_request: 128
},
diff --git a/src/ui/main/launch.rs b/src/ui/main/launch.rs
index fccd9d7..067b38e 100644
--- a/src/ui/main/launch.rs
+++ b/src/ui/main/launch.rs
@@ -11,8 +11,11 @@ pub fn launch(sender: ComponentSender) {
let config = Config::get().unwrap();
match config.launcher.behavior {
- // Disable launch button if behavior set to "Nothing" to prevent sussy actions
- LauncherBehavior::Nothing => sender.input(AppMsg::DisableButtons(true)),
+ // Disable launch button and show kill game button if behavior set to "Nothing" to prevent sussy actions
+ LauncherBehavior::Nothing => {
+ sender.input(AppMsg::DisableButtons(true));
+ sender.input(AppMsg::SetKillGameButton(true));
+ }
// Hide launcher window if behavior set to "Hide" or "Close"
LauncherBehavior::Hide | LauncherBehavior::Close => sender.input(AppMsg::HideWindow)
@@ -29,8 +32,11 @@ pub fn launch(sender: ComponentSender) {
}
match config.launcher.behavior {
- // Enable launch button if behavior set to "Nothing" after the game has closed
- LauncherBehavior::Nothing => sender.input(AppMsg::DisableButtons(false)),
+ // Enable launch button and hide kill game button if behavior set to "Nothing" after the game has closed
+ LauncherBehavior::Nothing => {
+ sender.input(AppMsg::DisableButtons(false));
+ sender.input(AppMsg::SetKillGameButton(false));
+ }
// Show back launcher window if behavior set to "Hide" and the game has closed
LauncherBehavior::Hide => sender.input(AppMsg::ShowWindow),
diff --git a/src/ui/main/mod.rs b/src/ui/main/mod.rs
index bdf0387..ab47c13 100644
--- a/src/ui/main/mod.rs
+++ b/src/ui/main/mod.rs
@@ -59,7 +59,9 @@ pub struct App {
state: Option,
downloading: bool,
- disabled_buttons: bool
+ disabled_buttons: bool,
+ kill_game_button: bool,
+ disabled_kill_game_button: bool
}
#[derive(Debug)]
@@ -89,6 +91,8 @@ pub enum AppMsg {
SetDownloading(bool),
DisableButtons(bool),
+ SetKillGameButton(bool),
+ DisableKillGameButton(bool),
OpenPreferences,
RepairGame,
@@ -219,7 +223,7 @@ impl SimpleComponent for App {
set_visible: model.style == LauncherStyle::Modern,
gtk::Picture {
- set_resource: Some("/org/app/images/icon.png"),
+ set_resource: Some(&format!("{APP_RESOURCE_PATH}/icons/hicolor/scalable/apps/{APP_ID}.png")),
set_vexpand: true,
set_content_fit: gtk::ContentFit::ScaleDown
},
@@ -395,6 +399,9 @@ impl SimpleComponent for App {
adw::Bin {
set_css_classes: &["background", "round-bin"],
+ #[watch]
+ set_visible: !model.kill_game_button,
+
gtk::Button {
adw::ButtonContent {
#[watch]
@@ -532,6 +539,48 @@ impl SimpleComponent for App {
}
},
+ adw::Bin {
+ set_css_classes: &["background", "round-bin"],
+
+ #[watch]
+ set_visible: model.kill_game_button,
+
+ gtk::Button {
+ adw::ButtonContent {
+ set_icon_name: "violence-symbolic", // window-close-symbolic
+ set_label: "Kill game process"
+ },
+
+ #[watch]
+ set_visible: model.kill_game_button,
+
+ #[watch]
+ set_sensitive: !model.disabled_kill_game_button,
+
+ set_css_classes: &["error", "pill"],
+
+ set_hexpand: false,
+ set_width_request: 200,
+
+ connect_clicked[sender] => move |_| {
+ sender.input(AppMsg::DisableKillGameButton(true));
+
+ std::thread::spawn(clone!(@strong sender => move || {
+ std::thread::sleep(std::time::Duration::from_secs(3));
+
+ sender.input(AppMsg::DisableKillGameButton(false));
+ }));
+
+ if let Err(err) = std::process::Command::new("pkill").arg("GenshinImpact.e").spawn() {
+ sender.input(AppMsg::Toast {
+ title: String::from("Failed to kill the game's process"),
+ description: Some(err.to_string())
+ });
+ }
+ }
+ }
+ },
+
adw::Bin {
set_css_classes: &["background", "round-bin"],
@@ -590,7 +639,9 @@ impl SimpleComponent for App {
state: None,
downloading: false,
- disabled_buttons: false
+ disabled_buttons: false,
+ kill_game_button: false,
+ disabled_kill_game_button: false
};
model.progress_bar.widget().set_halign(gtk::Align::Center);
@@ -1019,6 +1070,14 @@ impl SimpleComponent for App {
self.disabled_buttons = state;
}
+ AppMsg::SetKillGameButton(state) => {
+ self.kill_game_button = state;
+ }
+
+ AppMsg::DisableKillGameButton(state) => {
+ self.disabled_kill_game_button = state;
+ }
+
AppMsg::OpenPreferences => unsafe {
PREFERENCES_WINDOW.as_ref().unwrap_unchecked().widget().present();
}
diff --git a/src/ui/preferences/general/mod.rs b/src/ui/preferences/general/mod.rs
index c0a7e86..8ebecc5 100644
--- a/src/ui/preferences/general/mod.rs
+++ b/src/ui/preferences/general/mod.rs
@@ -188,7 +188,7 @@ impl SimpleAsyncComponent for GeneralApp {
set_active: model.style == LauncherStyle::Modern,
gtk::Image {
- set_from_resource: Some("/org/app/images/modern.svg")
+ set_resource: Some(&format!("{APP_RESOURCE_PATH}/images/modern.svg"))
},
connect_clicked => GeneralAppMsg::UpdateLauncherStyle(LauncherStyle::Modern)
@@ -214,7 +214,7 @@ impl SimpleAsyncComponent for GeneralApp {
set_active: model.style == LauncherStyle::Classic,
gtk::Image {
- set_from_resource: Some("/org/app/images/classic.svg")
+ set_resource: Some(&format!("{APP_RESOURCE_PATH}/images/classic.svg"))
},
connect_clicked => GeneralAppMsg::UpdateLauncherStyle(LauncherStyle::Classic)