refactor bg-image code and also add game icons

This commit is contained in:
RabbyDevs 2025-04-16 09:39:35 +03:00
parent 5b0168660f
commit 3138081d28
8 changed files with 173 additions and 333 deletions

274
Cargo.lock generated
View file

@ -18,6 +18,15 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046"
[[package]]
name = "addr2line"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli",
]
[[package]]
name = "adler2"
version = "2.0.0"
@ -129,126 +138,6 @@ dependencies = [
"libloading",
]
[[package]]
name = "async-channel"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
dependencies = [
"concurrent-queue",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-executor"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
"slab",
]
[[package]]
name = "async-fs"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
dependencies = [
"async-lock",
"blocking",
"futures-lite",
]
[[package]]
name = "async-io"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059"
dependencies = [
"async-lock",
"cfg-if",
"concurrent-queue",
"futures-io",
"futures-lite",
"parking",
"polling",
"rustix 0.38.44",
"slab",
"tracing",
"windows-sys 0.59.0",
]
[[package]]
name = "async-lock"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
dependencies = [
"event-listener",
"event-listener-strategy",
"pin-project-lite",
]
[[package]]
name = "async-net"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
dependencies = [
"async-io",
"blocking",
"futures-lite",
]
[[package]]
name = "async-process"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb"
dependencies = [
"async-channel",
"async-io",
"async-lock",
"async-signal",
"async-task",
"blocking",
"cfg-if",
"event-listener",
"futures-lite",
"rustix 0.38.44",
"tracing",
]
[[package]]
name = "async-signal"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3"
dependencies = [
"async-io",
"async-lock",
"atomic-waker",
"cfg-if",
"futures-core",
"futures-io",
"rustix 0.38.44",
"signal-hook-registry",
"slab",
"windows-sys 0.59.0",
]
[[package]]
name = "async-task"
version = "4.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
[[package]]
name = "atomic-waker"
version = "1.1.2"
@ -290,6 +179,21 @@ dependencies = [
"arrayvec",
]
[[package]]
name = "backtrace"
version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets 0.52.6",
]
[[package]]
name = "bit-set"
version = "0.8.0"
@ -356,19 +260,6 @@ dependencies = [
"objc2",
]
[[package]]
name = "blocking"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea"
dependencies = [
"async-channel",
"async-task",
"futures-io",
"futures-lite",
"piper",
]
[[package]]
name = "built"
version = "0.7.7"
@ -905,27 +796,6 @@ dependencies = [
"num-traits",
]
[[package]]
name = "event-listener"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
dependencies = [
"event-listener",
"pin-project-lite",
]
[[package]]
name = "exr"
version = "1.73.0"
@ -956,6 +826,12 @@ dependencies = [
"simd-adler32",
]
[[package]]
name = "file-format"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ef3d5e8ae27277c8285ac43ed153158178ef0f79567f32024ca8140a0c7cd8"
[[package]]
name = "flate2"
version = "1.1.1"
@ -1088,19 +964,6 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-lite"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"parking",
"pin-project-lite",
]
[[package]]
name = "futures-macro"
version = "0.3.31"
@ -1195,6 +1058,12 @@ dependencies = [
"weezl",
]
[[package]]
name = "gimli"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "gio-sys"
version = "0.20.9"
@ -1542,7 +1411,7 @@ dependencies = [
"iced_core",
"log",
"rustc-hash 2.1.1",
"smol",
"tokio",
"wasm-bindgen-futures",
"wasmtimer",
]
@ -2552,6 +2421,15 @@ dependencies = [
"objc2-foundation",
]
[[package]]
name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.21.3"
@ -2600,12 +2478,6 @@ dependencies = [
"ttf-parser 0.25.1",
]
[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "parking_lot"
version = "0.12.3"
@ -2673,17 +2545,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "piper"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
dependencies = [
"atomic-waker",
"fastrand",
"futures-io",
]
[[package]]
name = "pkg-config"
version = "0.3.32"
@ -2977,6 +2838,7 @@ name = "reversed-rooms-launcher"
version = "0.1.0"
dependencies = [
"directories",
"file-format",
"iced",
"iced_video_player",
"image",
@ -3033,6 +2895,12 @@ dependencies = [
"walkdir",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
@ -3198,15 +3066,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
dependencies = [
"libc",
]
[[package]]
name = "simd-adler32"
version = "0.3.7"
@ -3292,23 +3151,6 @@ dependencies = [
"wayland-backend",
]
[[package]]
name = "smol"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f"
dependencies = [
"async-channel",
"async-executor",
"async-fs",
"async-io",
"async-lock",
"async-net",
"async-process",
"blocking",
"futures-lite",
]
[[package]]
name = "smol_str"
version = "0.2.2"
@ -3616,6 +3458,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.44.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
dependencies = [
"backtrace",
"pin-project-lite",
]
[[package]]
name = "toml"
version = "0.8.20"

View file

@ -6,11 +6,18 @@ edition = "2024"
[dependencies]
directories = "6.0.0"
iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["smol", "tiny-skia", "image"], default-features = false }
iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["tokio", "tiny-skia", "wgpu", "image"], default-features = false }
image = "0.25.6"
serde = { version = "1.0.219", features = ["serde_derive"] }
serde_json = "1.0.140"
tempfile = "3.19.1"
iced_video_player = {path = "./iced_video_player"}
url = "2.5.4"
rust-embed = "8.7.0"
rust-embed = "8.7.0"
file-format = "0.26.0"
[profile.release]
strip = true # Automatically strip symbols from the binary.
lto = true # Link-time optimization.
opt-level = 3 # Optimize for speed.
codegen-units = 1 # Maximum size reduction optimizations.

View file

@ -16,7 +16,7 @@ exclude = [
]
[dependencies]
iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["smol", "wgpu", "image", "advanced"], default-features = false }
iced = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e", features = ["tokio", "wgpu", "image", "advanced"], default-features = false }
iced_wgpu = { git = "https://github.com/iced-rs/iced.git", rev = "482d54118a733231cdceb4ab8eef2419fbec385e" }
gstreamer = "0.23.5"
gstreamer-app = "0.23.5" # appsink

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

View file

@ -1,4 +1,5 @@
#![feature(let_chains)]
use file_format::FileFormat;
use ::image::ImageReader;
use iced::{
Alignment::Center,
@ -11,9 +12,7 @@ use iced::{
use iced_video_player::{Video, VideoPlayer};
use serde::{Deserialize, Serialize};
use std::{
fs::{self, create_dir_all, read_to_string},
io::{Cursor, Write},
thread::sleep,
fs::{self, create_dir_all, read_to_string}, io::{Cursor, Write}, path::PathBuf, thread::sleep
};
use tempfile::NamedTempFile;
@ -52,7 +51,6 @@ pub fn main() -> iced::Result {
};
iced::application(Launcher::boot, Launcher::update, Launcher::view)
// .subscription(Launcher::subscription)
.title(Launcher::title)
.window(settings)
.window_size((1280.0, 760.0))
@ -79,7 +77,7 @@ struct State {
selected_game: PossibleGames,
installed_games: Vec<PossibleGames>,
installed_game_servers: Vec<PossibleGames>,
db_software_installed: bool,
db_software_installed: bool
}
#[derive(Debug, Default, Serialize, Deserialize)]
@ -109,7 +107,7 @@ enum Message {
}
impl State {
fn path() -> std::path::PathBuf {
fn path() -> PathBuf {
let mut path = if let Some(project_dirs) =
directories::ProjectDirs::from("rs", "reversed-rooms", "launcher")
{
@ -162,12 +160,85 @@ impl State {
}
}
fn deg_to_rad(deg: f32) -> f32 {
fn rad(deg: f32) -> f32 {
deg * std::f32::consts::PI / 180.0
}
fn get_game_background(game: &PossibleGames) -> Element<Message> {
let file_path: &str = match game {
PossibleGames::WutheringWaves => "wutheringwaves-bg.mp4",
PossibleGames::ZenlessZoneZero => "zenlesszonezero-bg.png",
PossibleGames::HonkaiStarRail => "honkaistarrail-bg.png",
PossibleGames::GenshinImpact => "genshinimpact-bg.png",
};
if let Some(file) = Assets::get(file_path) {
let file_format = FileFormat::from_bytes(file.data.clone());
if file_format.extension() == "mp4" {
let mut temp_file = NamedTempFile::new().unwrap();
temp_file.write_all(&file.data.clone()).unwrap();
let temp_path = temp_file.path().to_str().unwrap().to_string();
let mut video =
Video::new(url::Url::from_file_path(temp_path).unwrap()).unwrap();
video.set_looping(true);
VideoPlayer::new(video).into()
} else {
let img = ImageReader::new(Cursor::new(&file.data))
.with_guessed_format()
.unwrap()
.decode()
.unwrap();
let handle = image::Handle::from_rgba(
img.width(),
img.height(),
img.to_rgba8().into_raw()
);
image(handle).content_fit(iced::ContentFit::Fill).into()
}
} else {
panic!("Missing icon for {:?}, path: {}", game, file_path)
}
}
fn get_game_icon(game: &PossibleGames) -> Element<Message> {
let file_path: &str = match game {
PossibleGames::WutheringWaves => "wutheringwaves-icon.png",
PossibleGames::ZenlessZoneZero => "zenlesszonezero-icon.png",
PossibleGames::HonkaiStarRail => "honkaistarrail-icon.png",
PossibleGames::GenshinImpact => "genshinimpact-icon.png",
};
if let Some(img_file) = Assets::get(file_path) {
let img = ImageReader::new(Cursor::new(img_file.data))
.with_guessed_format()
.unwrap()
.decode()
.unwrap()
.resize(126, 126, ::image::imageops::FilterType::Lanczos3);
let handle = image::Handle::from_rgba(
img.width(),
img.height(),
img.to_rgba8().into_raw()
);
container(image(handle).content_fit(iced::ContentFit::Contain).height(Length::Fixed(64.0)).filter_method(image::FilterMethod::Linear))
.style(move |_| {
container::Style {
// text_color: Color::from_rgba8(0, 0, 0, 1.0).into(),
// background: Some(Color::from_rgba8(255, 255, 255, 1.0).into()),
border: border::rounded(20),
..container::Style::default()
}
})
.into()
} else {
panic!("Missing icon for {:?}, path: {}", game, file_path)
}
}
fn style_container(direction: f32) -> container::Style {
let angle = deg_to_rad(direction);
let angle = rad(direction);
container::Style {
text_color: Color::from_rgba8(255, 255, 255, 1.0).into(),
background: Some(
@ -202,11 +273,30 @@ impl Launcher {
}
fn view(&self) -> Element<Message> {
let game_selector = container(
row![
get_game_icon(&PossibleGames::WutheringWaves),
get_game_icon(&PossibleGames::ZenlessZoneZero),
get_game_icon(&PossibleGames::HonkaiStarRail),
get_game_icon(&PossibleGames::GenshinImpact),
// text("test").size(25),
// text("test").size(25),
]
.spacing(10),
)
// .padding(10)
.align_y(Top)
.align_x(Center)
.width(Length::Fill);
let topbar = container(row![
text("launcher... goog...").size(25),
text("Reversed Rooms").size(25),
Space::new(Length::Fill, Length::Fixed(0.0)),
game_selector,
Space::new(Length::Fill, Length::Fixed(0.0)),
text("rabbydevs").size(25),
])
.height(Length::Fill)
.width(Length::Fill)
.style(move |_| style_container(0.0))
.padding(10);
@ -233,121 +323,12 @@ impl Launcher {
column![topbar, Space::new(Length::Fill, Length::Fill), bottom_bar].width(Length::Fill);
let content = container(user_area).center(Length::Fill);
let game_selector = container(
row![
text("test").size(25),
text("test").size(25),
text("test").size(25),
]
.spacing(10),
)
.padding(10)
.align_y(Top)
.align_x(Center)
.width(Length::Fill);
fn get_game_background(game: &PossibleGames, _video: Option<Video>) -> iced::widget::Image<image::Handle> {
match game {
PossibleGames::WutheringWaves => panic!("wuwa doesnt have a image lmao?"),
PossibleGames::ZenlessZoneZero => {
if let Some(img_file) = Assets::get("zenlesszonezero-bg.png") {
let img = ImageReader::new(Cursor::new(img_file.data))
.with_guessed_format()
.unwrap()
.decode()
.unwrap();
let handle = image::Handle::from_rgba(
img.width(),
img.height(),
img.to_rgba8().into_raw()
);
return image(handle).content_fit(iced::ContentFit::Fill);
}
},
PossibleGames::HonkaiStarRail => {
if let Some(img_file) = Assets::get("honkaistarrail-bg.png") {
let img = ImageReader::new(Cursor::new(img_file.data))
.with_guessed_format()
.unwrap()
.decode()
.unwrap();
let handle = image::Handle::from_rgba(
img.width(),
img.height(),
img.to_rgba8().into_raw()
);
return image(handle).content_fit(iced::ContentFit::Fill);
}
},
PossibleGames::GenshinImpact => {
if let Some(img_file) = Assets::get("genshinimpact-bg.png") {
let img = ImageReader::new(Cursor::new(img_file.data))
.with_guessed_format()
.unwrap()
.decode()
.unwrap();
let handle = image::Handle::from_rgba(
img.width(),
img.height(),
img.to_rgba8().into_raw()
);
return image(handle).content_fit(iced::ContentFit::Fill);
}
}
}
let bg_file = Assets::get("placeholder.png").unwrap();
let bg_image = ImageReader::new(Cursor::new(bg_file.data))
.with_guessed_format()
.unwrap()
.decode()
.unwrap();
let handle = image::Handle::from_rgba(
bg_image.width(),
bg_image.height(),
bg_image.to_rgba8().into_raw()
);
image(handle).content_fit(iced::ContentFit::Fill)
}
println!("whuh");
match self {
Launcher::Loading => loading_message(),
Launcher::Loaded(state) => {
match state.selected_game {
PossibleGames::WutheringWaves => {
let video_file = Assets::get("wutheringwaves-bg.mp4").unwrap();
let mut temp_file = NamedTempFile::new().unwrap();
temp_file.write_all(&video_file.data).unwrap();
temp_file.flush().unwrap();
let temp_path = temp_file.path().to_str().unwrap().to_string();
let mut video =
Video::new(url::Url::from_file_path(temp_path).unwrap()).unwrap();
video.set_looping(true);
let game_video = video;
let player = VideoPlayer::new(game_video);
stack![player, content, game_selector,].into()
}
PossibleGames::ZenlessZoneZero => {
let bg_image = get_game_background(&state.selected_game, None);
stack![bg_image, content, game_selector].into()
}
PossibleGames::HonkaiStarRail => {
let bg_image = get_game_background(&state.selected_game, None);
stack![bg_image, content, game_selector].into()
}
PossibleGames::GenshinImpact => {
let bg_image = get_game_background(&state.selected_game, None);
stack![bg_image, content, game_selector].into()
}
}
stack![get_game_background(&state.selected_game), content].into()
}
}
}