From ddf8c5fe5eda7a5df794f5078bb9e0c089488c9b Mon Sep 17 00:00:00 2001 From: jika Date: Sat, 5 Aug 2023 17:02:46 +0200 Subject: [PATCH] Rearange file structure and add coop_widget --- Cargo.lock | 6 ++ lib/src/lib.rs | 6 ++ lib/src/tcp/mod.rs | 22 +++--- remote/Cargo.toml | 5 +- remote/build.rs | 3 +- remote/icons/{ => media-controls}/back.png | Bin remote/icons/{ => media-controls}/loop.png | Bin remote/icons/{ => media-controls}/pause.png | Bin .../icons/{ => media-controls}/play-pause.png | Bin remote/icons/{ => media-controls}/play.png | Bin remote/icons/{ => media-controls}/rec.png | Bin remote/icons/{ => media-controls}/shuffle.png | Bin remote/icons/{ => media-controls}/skip.png | Bin remote/icons/{ => media-controls}/stop.png | Bin remote/src/controller/media.rs | 47 +++++++++++++ remote/src/controller/mod.rs | 1 + remote/src/link/mod.rs | 25 +++++++ remote/src/main.rs | 65 +++--------------- remote/ui/_imports/coop-widgets.slint | 25 +++++++ remote/ui/app.slint | 8 +++ remote/ui/appwindow.slint | 25 ------- remote/ui/widgets/mediacontrols.slint | 34 ++++++--- 22 files changed, 169 insertions(+), 103 deletions(-) rename remote/icons/{ => media-controls}/back.png (100%) rename remote/icons/{ => media-controls}/loop.png (100%) rename remote/icons/{ => media-controls}/pause.png (100%) rename remote/icons/{ => media-controls}/play-pause.png (100%) rename remote/icons/{ => media-controls}/play.png (100%) rename remote/icons/{ => media-controls}/rec.png (100%) rename remote/icons/{ => media-controls}/shuffle.png (100%) rename remote/icons/{ => media-controls}/skip.png (100%) rename remote/icons/{ => media-controls}/stop.png (100%) create mode 100644 remote/src/controller/media.rs create mode 100644 remote/src/controller/mod.rs create mode 100644 remote/src/link/mod.rs create mode 100644 remote/ui/_imports/coop-widgets.slint create mode 100644 remote/ui/app.slint delete mode 100644 remote/ui/appwindow.slint diff --git a/Cargo.lock b/Cargo.lock index 4fcaab2..a232371 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,6 +646,11 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "coop_widgets" +version = "0.1.0" +source = "git+https://codeberg.org/flovansl/co_sl#35ae498f0b02a82788a32dc02aa9018ab0a5d65c" + [[package]] name = "copypasta" version = "0.8.2" @@ -2697,6 +2702,7 @@ name = "remote" version = "0.1.0" dependencies = [ "anyhow", + "coop_widgets", "env_logger", "lib", "log", diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 6b9d69a..8f4dcac 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1,6 +1,7 @@ pub mod tcp; use std::fmt::{Debug, Display}; +use crossbeam::channel::{Sender, Receiver}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] @@ -16,6 +17,11 @@ pub enum ServerMessage { Playing(bool), } +pub type MessageToServer = Sender; +pub type MessageFromServer = Receiver; +pub type MessageToClient = Sender; +pub type MessageFomClient = Receiver; + pub enum Origin { Server, Client, diff --git a/lib/src/tcp/mod.rs b/lib/src/tcp/mod.rs index 67ca64e..db5354a 100644 --- a/lib/src/tcp/mod.rs +++ b/lib/src/tcp/mod.rs @@ -80,9 +80,9 @@ where Ok(()) } -pub fn start_server() -> Result<(Sender, Receiver)> { - let (sender_c, reciever_c) = channel::bounded(4); - let (sender_s, reciever_s) = channel::bounded(4); +pub fn start_server() -> Result<(MessageToClient, MessageFomClient)> { + let (message_to_server, message_from_client) = channel::bounded(4); + let (message_to_client, message_from_server) = channel::bounded(4); let server = create_listener("0.0.0.0", PORT); info!("Listening on port {}", PORT); @@ -93,8 +93,8 @@ pub fn start_server() -> Result<(Sender, Receiver) thread::sleep(Duration::from_millis(500)); match stream_result { Ok(stream) => { - let reciever_s = reciever_s.clone(); - let sender_c = sender_c.clone(); + let reciever_s = message_from_server.clone(); + let sender_c = message_to_server.clone(); thread::spawn(move || { if let Err(error) = @@ -110,19 +110,19 @@ pub fn start_server() -> Result<(Sender, Receiver) } }); - Ok((sender_s, reciever_c)) + Ok((message_to_client, message_from_client)) } -pub fn start_client(ip: IpAddr) -> Result<(Sender, Receiver)> { - let (sender_c, reciever_c) = channel::bounded(4); - let (sender_s, reciever_s) = channel::bounded(4); +pub fn start_client(ip: IpAddr) -> Result<(MessageToServer, MessageFromServer)> { + let (message_to_server, message_from_client) = channel::bounded(4); + let (message_to_client, message_from_server) = channel::bounded(4); let serv_addr = SocketAddr::new(ip, PORT); let server = TcpStream::connect(serv_addr)?; info!("Connected successfully to {}", serv_addr); - thread::spawn(move || handle_connection(server, reciever_c, sender_s, Origin::Server)); + thread::spawn(move || handle_connection(server, message_from_client, message_to_client, Origin::Server)); - Ok((sender_c, reciever_s)) + Ok((message_to_server, message_from_server)) } diff --git a/remote/Cargo.toml b/remote/Cargo.toml index 17a59b6..78360b7 100644 --- a/remote/Cargo.toml +++ b/remote/Cargo.toml @@ -17,7 +17,8 @@ anyhow = "1.0" log = "0.4" env_logger = "0.10" -slint = "1.0" +slint = "1.1" [build-dependencies] -slint-build = "1.0" +slint-build = "1.1" +coop_widgets = { git = "https://codeberg.org/flovansl/co_sl" } diff --git a/remote/build.rs b/remote/build.rs index 0a2d8aa..12a1d26 100644 --- a/remote/build.rs +++ b/remote/build.rs @@ -1,3 +1,4 @@ fn main() { - slint_build::compile("ui/appwindow.slint").unwrap(); + coop_widgets::generate_import().unwrap(); + slint_build::compile("ui/app.slint").unwrap(); } diff --git a/remote/icons/back.png b/remote/icons/media-controls/back.png similarity index 100% rename from remote/icons/back.png rename to remote/icons/media-controls/back.png diff --git a/remote/icons/loop.png b/remote/icons/media-controls/loop.png similarity index 100% rename from remote/icons/loop.png rename to remote/icons/media-controls/loop.png diff --git a/remote/icons/pause.png b/remote/icons/media-controls/pause.png similarity index 100% rename from remote/icons/pause.png rename to remote/icons/media-controls/pause.png diff --git a/remote/icons/play-pause.png b/remote/icons/media-controls/play-pause.png similarity index 100% rename from remote/icons/play-pause.png rename to remote/icons/media-controls/play-pause.png diff --git a/remote/icons/play.png b/remote/icons/media-controls/play.png similarity index 100% rename from remote/icons/play.png rename to remote/icons/media-controls/play.png diff --git a/remote/icons/rec.png b/remote/icons/media-controls/rec.png similarity index 100% rename from remote/icons/rec.png rename to remote/icons/media-controls/rec.png diff --git a/remote/icons/shuffle.png b/remote/icons/media-controls/shuffle.png similarity index 100% rename from remote/icons/shuffle.png rename to remote/icons/media-controls/shuffle.png diff --git a/remote/icons/skip.png b/remote/icons/media-controls/skip.png similarity index 100% rename from remote/icons/skip.png rename to remote/icons/media-controls/skip.png diff --git a/remote/icons/stop.png b/remote/icons/media-controls/stop.png similarity index 100% rename from remote/icons/stop.png rename to remote/icons/media-controls/stop.png diff --git a/remote/src/controller/media.rs b/remote/src/controller/media.rs new file mode 100644 index 0000000..e66f299 --- /dev/null +++ b/remote/src/controller/media.rs @@ -0,0 +1,47 @@ +use std::{thread, time::Duration}; + +use lib::{ClientMessage, MessageFromServer, MessageToServer, ServerMessage}; +use log::info; + +use slint::ComponentHandle; +use crate::{App,MediaLogic}; + +pub fn init(ui: &App, sender_co: MessageToServer, receiver_s: MessageFromServer) { + let sender_c = sender_co.clone(); + + ui.global::().on_play_pause(move || { + sender_c.send(ClientMessage::PlayPause).unwrap(); + }); + + let sender_c = sender_co.clone(); + ui.global::().on_next(move || { + sender_c.send(ClientMessage::Next).unwrap(); + }); + + let sender_c = sender_co.clone(); + ui.global::().on_previous(move || { + sender_c.send(ClientMessage::Previous).unwrap(); + }); + + let ui_handle = ui.as_weak(); + thread::spawn(move || loop { + if receiver_s.is_empty() { + thread::sleep(Duration::from_millis(200)); + continue; + } + let msg = receiver_s.recv().unwrap(); + info!("Received : {msg:?}"); + match msg { + ServerMessage::NowPlaying(title) => ui_handle + .upgrade_in_event_loop(move |handle| { + handle.global::().set_now_playing(title.into()) + }) + .unwrap(), + ServerMessage::Playing(bool) => ui_handle + .upgrade_in_event_loop(move |handle| { + handle.global::().set_playing(bool) + }) + .unwrap(), + }; + }); +} diff --git a/remote/src/controller/mod.rs b/remote/src/controller/mod.rs new file mode 100644 index 0000000..b30398d --- /dev/null +++ b/remote/src/controller/mod.rs @@ -0,0 +1 @@ +pub mod media; diff --git a/remote/src/link/mod.rs b/remote/src/link/mod.rs new file mode 100644 index 0000000..9203a10 --- /dev/null +++ b/remote/src/link/mod.rs @@ -0,0 +1,25 @@ +use lib::{tcp::start_client, MessageToServer, MessageFromServer}; +use log::info; +use std::{net::IpAddr, process::exit, str::FromStr, thread, time::Duration}; + +pub fn init_tcp() -> (MessageToServer, MessageFromServer){ + info!("Trying to connect ot server"); + let mut retries = 1; + let (messages_to_server, message_from_server) = loop { + let res = start_client(IpAddr::from_str("127.0.0.1").unwrap()); + if let Ok((s, r)) = res { + break (s, r); + } + println!("Failde to connect retrying in {} ms", 200 * retries); + thread::sleep(Duration::from_millis(200 * retries)); + retries *= 5; + if retries >= 500 { + println!("Could not connect to server exiting..."); + exit(0); + } + }; + + info!("Connected to Server"); + + (messages_to_server, message_from_server) +} diff --git a/remote/src/main.rs b/remote/src/main.rs index 1f42612..b4e4a4d 100644 --- a/remote/src/main.rs +++ b/remote/src/main.rs @@ -1,70 +1,23 @@ -use std::{net::IpAddr, process::exit, str::FromStr, thread, time::Duration}; +mod controller; +mod link; -use lib::{tcp::start_client, ServerMessage}; use log::info; +use crate::{controller::media, link::init_tcp}; + slint::include_modules!(); fn main() -> Result<(), slint::PlatformError> { env_logger::init_from_env( env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), ); + + let (messages_to_server, message_from_server) = init_tcp(); - let mut retries = 1; - let (sender_co, receiver_s) = loop { - let res = start_client(IpAddr::from_str("127.0.0.1").unwrap()); - if let Ok((s, r)) = res { - break (s, r); - } - println!("Failde to connect retrying in {} ms", 200 * retries); - thread::sleep(Duration::from_millis(200 * retries)); - retries *= 5; - if retries >= 500 { - println!("Could not connect to server exiting..."); - exit(1); - } - }; - - info!("Connected to Server"); - - let ui = AppWindow::new()?; - - let sender_c = sender_co.clone(); - - ui.global::().on_play_pause(move || { - sender_c.send(lib::ClientMessage::PlayPause).unwrap(); - }); - - let sender_c = sender_co.clone(); - ui.global::().on_next(move || { - sender_c.send(lib::ClientMessage::Next).unwrap(); - }); - - let sender_c = sender_co.clone(); - ui.global::().on_previous(move || { - sender_c.send(lib::ClientMessage::Previous).unwrap(); - }); - - let ui_handle = ui.as_weak(); - thread::spawn(move || loop { - if receiver_s.is_empty() { - thread::sleep(Duration::from_millis(200)); - continue; - } - let msg = receiver_s.recv().unwrap(); - info!("Received : {msg:?}"); - match msg { - ServerMessage::NowPlaying(title) => ui_handle - .upgrade_in_event_loop(move |handle| handle.set_now_playing(title.into())) - .unwrap(), - ServerMessage::Playing(bool) => ui_handle - .upgrade_in_event_loop(move |handle| { - handle.global::().set_playing(bool) - }) - .unwrap(), - }; - }); + let ui = App::new()?; + media::init(&ui, messages_to_server, message_from_server); + info!("Launching UI"); ui.run() } diff --git a/remote/ui/_imports/coop-widgets.slint b/remote/ui/_imports/coop-widgets.slint new file mode 100644 index 0000000..ded7a01 --- /dev/null +++ b/remote/ui/_imports/coop-widgets.slint @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2022 Florian Blasius +// SPDX-License-Identifier: MIT + +import { Duration, Icography, Icons, Radius, ColorVariant, ColorTheme, CoopPalette, CosmicPalette, Palette, Size, State, Space, Typography } from "/home/jika/.cargo/git/checkouts/co_sl-418b266b7ff25a3f/35ae498/widgets/coop_widgets/ui/styling/styling.slint"; +export { Duration, Icography, Icons, Radius, ColorVariant, ColorTheme, CoopPalette, CosmicPalette, Palette, Size, State, Space, Typography } + +import { HeaderBar, SideBar } from "/home/jika/.cargo/git/checkouts/co_sl-418b266b7ff25a3f/35ae498/widgets/coop_widgets/ui/building-blocks/building-blocks.slint"; +export { HeaderBar, SideBar } + +import { CoopWindow, FocusTouchArea, SmallLabel, MediumLabel, LargeLabel, ErrorLabel, SmallTitle, MediumTitle, LargeTitle, Popup, PopupBorder, + ThemedWindow } from "/home/jika/.cargo/git/checkouts/co_sl-418b266b7ff25a3f/35ae498/widgets/coop_widgets/ui/components/components.slint"; +export { CoopWindow, FocusTouchArea, SmallLabel, MediumLabel, LargeLabel, ErrorLabel, SmallTitle, MediumTitle, LargeTitle, Popup, PopupBorder, ThemedWindow } + +import { Button, OutlineButton, RoundButton, Carousel, ComboBox, ListViewItem, GroupListViewItem, ListView, GroupListView, ItemDelegate, + ScrollView, LineEdit, RoundOutlineButton, Switch, CheckBox, CheckableBase, Slider, StandardTableView, ProgressIndicator, StandardListView } from "/home/jika/.cargo/git/checkouts/co_sl-418b266b7ff25a3f/35ae498/widgets/coop_widgets/ui/widgets/widgets.slint"; +export { Button, ComboBox, OutlineButton, RoundButton, Carousel, ListViewItem, GroupListViewItem, ListView, GroupListView, ItemDelegate, + ScrollView, LineEdit, RoundOutlineButton, CheckBox, Switch, CheckableBase, Slider, StandardTableView, ProgressIndicator, StandardListView } + +import { VirtualKeyboard, VirtualKeyboardHandler, KeyModel } from "/home/jika/.cargo/git/checkouts/co_sl-418b266b7ff25a3f/35ae498/widgets/coop_widgets/ui/keyboard/keyboard.slint"; +export { VirtualKeyboard, VirtualKeyboardHandler, KeyModel } + +import { CenterLayout, FormElement, VerticalSeparator, HorizontalSeparator, Spacer, VerticalSpacerSmall, VerticalSpacerMedium, VerticalSpacerLarge, + HorizontalSpacerSmall, HorizontalSpacerMedium, HorizontalSpacerLarge } from "/home/jika/.cargo/git/checkouts/co_sl-418b266b7ff25a3f/35ae498/widgets/coop_widgets/ui/layouts/layouts.slint"; +export { CenterLayout, FormElement, VerticalSeparator, HorizontalSeparator, Spacer, VerticalSpacerSmall, VerticalSpacerMedium, VerticalSpacerLarge, + HorizontalSpacerSmall, HorizontalSpacerMedium, HorizontalSpacerLarge } \ No newline at end of file diff --git a/remote/ui/app.slint b/remote/ui/app.slint new file mode 100644 index 0000000..1731717 --- /dev/null +++ b/remote/ui/app.slint @@ -0,0 +1,8 @@ +import { MediaControls, MediaLogic } from "widgets/mediacontrols.slint"; +export { MediaLogic } + + +export component App inherits Window { + background: white; + MediaControls {} +} diff --git a/remote/ui/appwindow.slint b/remote/ui/appwindow.slint deleted file mode 100644 index 402d695..0000000 --- a/remote/ui/appwindow.slint +++ /dev/null @@ -1,25 +0,0 @@ -import { Button, VerticalBox } from "std-widgets.slint"; -import { MediaControls, MediaLogic } from "widgets/mediacontrols.slint"; -export { MediaLogic } - - -export component AppWindow inherits Window { - background: white; - in-out property now_playing: "Loading..."; - - VerticalLayout { - alignment: center; - - MediaControls { } - Text { - horizontal-alignment: center; - color: black; - text: root.now_playing; - font-size:35px; - font-weight: 600; - wrap: word-wrap; - } - } - - -} diff --git a/remote/ui/widgets/mediacontrols.slint b/remote/ui/widgets/mediacontrols.slint index 82dc251..b09304f 100644 --- a/remote/ui/widgets/mediacontrols.slint +++ b/remote/ui/widgets/mediacontrols.slint @@ -1,38 +1,56 @@ import { Clickable } from "clickable.slint"; -import { HorizontalBox } from "std-widgets.slint"; export global MediaLogic { pure callback play-pause(); pure callback next(); pure callback previous(); in-out property playing; + in-out property now_playing: "Loading..."; } -export component MediaControls inherits Clickable { - in-out property playing: false; - - HorizontalBox { +export component Buttons { + HorizontalLayout { width: 450px; Clickable { - icon: @image-url("../../icons/back.png"); + icon: @image-url("../../icons/media-controls/back.png"); action => { MediaLogic.previous(); } } Clickable { - icon: MediaLogic.playing ? @image-url("../../icons/pause.png"): @image-url("../../icons/play.png"); + icon: MediaLogic.playing ? @image-url("../../icons/media-controls/pause.png"): @image-url("../../icons/media-controls/play.png"); action => { MediaLogic.playing = !MediaLogic.playing; MediaLogic.play-pause(); } } Clickable { - icon: @image-url("../../icons/skip.png"); + icon: @image-url("../../icons/media-controls/skip.png"); action => { MediaLogic.next(); } } } +} + +export component MediaControls inherits Clickable { + + VerticalLayout { + alignment: center; + + Buttons { } + Text { + horizontal-alignment: center; + color: black; + text: MediaLogic.now_playing; + font-size:35px; + font-weight: 600; + wrap: word-wrap; + } + } + + + }