From 41420d3080c2d2c262fc43a108b9acc1863820b8 Mon Sep 17 00:00:00 2001 From: Fl1tzi Date: Tue, 25 Jul 2023 17:10:39 +0200 Subject: [PATCH] complete folder switching, temporary icon --- fonts/README.md | 5 -- fonts/SpaceGrotesk-LICENSE | 94 ------------------------------------- fonts/SpaceGrotesk.ttf | Bin 86504 -> 0 bytes src/device.rs | 35 +++++++++----- src/modules.rs | 79 ++++++++++++++++++++++++------- src/modules/space.rs | 13 ++++- 6 files changed, 97 insertions(+), 129 deletions(-) delete mode 100644 fonts/README.md delete mode 100644 fonts/SpaceGrotesk-LICENSE delete mode 100644 fonts/SpaceGrotesk.ttf diff --git a/fonts/README.md b/fonts/README.md deleted file mode 100644 index cf2bc20..0000000 --- a/fonts/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Fonts - -This folder holds all fonts which may be used by the modules. - -Thanks to the creators of these awesome fonts! diff --git a/fonts/SpaceGrotesk-LICENSE b/fonts/SpaceGrotesk-LICENSE deleted file mode 100644 index 579cdbf..0000000 --- a/fonts/SpaceGrotesk-LICENSE +++ /dev/null @@ -1,94 +0,0 @@ -Copyright 2020 The Space Grotesk Project Authors (https://github.com/floriankarsten/space-grotesk) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. - diff --git a/fonts/SpaceGrotesk.ttf b/fonts/SpaceGrotesk.ttf deleted file mode 100644 index d0e5eff1ff43b884f3507892a489da65a1ae71d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86504 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 =cQ1iXvnlcLl7F76Y}%) z+w@X?zm};a0LVspszvivt$O_$V)JC=4h;q(4H|h!*67#!Wj%C`v_R*|rq;H`R@vOz z*3v559?)~!_1pBs^}fm&Uu#BH)GsNJTq1ZB_`yXrwd9vq)I(QPR~7j4E2|b4L?t!V zE8x^p23oVcAX0fki^lJz>0N1Bga)U*qVkCpyELR~1BQL=dF6lj$>ZK9`yOjVk7IWv z<@(coY`?%)d8Oz7A*ly%g@nH>Nu%`qs65@zBx!t_^4XmCgJfT}q{q)DDc%psbtWaL z?@rV2pa=3|ou1#H9RIQAJTv&8iRG@VGxW+z3j&=G=;T1d zbIX|2qoV>H6KHmz;{#Q{9E+8qR1r>#rJ%GZ(60ts9B7auX!d$Ec`~mI`TRf&p=veY zdjdM7-@VTYxm@fEU5TPSpgg$v%PL2|CVydl*l6sP;gw+%uoW(>4*N1Th>a(yy&D$` z?HLzf%i4Gxy0Oja2|0=LXv5>!toBQlM&fVB^hM6UjE{5T+&Dj;29J?r@prQS!1j~4 zkiE&aP=D-gF1FMaF10f2Ly<{LVm2g31?ju&SD%#r&Esl;o9gNzoAcXkWx_zKT`PkdywZF z{83(#!W+&15~G<668rpB;-0@o%<~gOJ0GGfwM9=-@8WPa>t@Jn>-D5{B%GVzJe_h_ zaTC>G49wR)!U~01Iy(7N0~E#HEApaS z?;52G&)B)35n5X^lMRp7Y+CxW#_Q$I8TAFu$@v23sQv$0_a^>BGY%W=Ft*u#d(0kW zo_X2+)b0Z<>;W0<#RmHcZKA$TTd)IP#oF7!{L~lxsUNl9x9#?E+lejqx*d|max-N= z;CU^VPIDv3)qJq33UHt@5T1qTg$rB;97WNUcF-B@H+nPI^}7<+;kL?QIpEg0dt{f3 znK63gh|6*_+`X>ZJ?b8J1C%~X=|1qHc2N3W*^kcLAe}C{d}((E+-rucM8m0(TDhGV z8cniR2tzI#Si`!B2pWS#&p6Af+2w9KSMLV7WEJV>I_G(#7Tz2gF9lK|v!zTXU@OgY zv#|9hV%J@R4fhr7wIXb@Y1m<3!{#c*vRX)edrfs{)pP}`+n2WPrM(f_`_ftxDdoD| z3vR!gWrzFYqTWmUW`w)ZzDuMXIM(nJC;mB8C(C5HER|c_*IlXGAWP&9xk;XJ{#r+YN4s zyO}-$*<)K1w)@oylNhx!;N5Zi+lG{zH?^p0M^<93qf0nlQevg0N z_xN6NFZv_?nC~Zd+z^h zf9k@O{ZaTTDe^;#CweG7JBQRZ#kN)SG=r7d&J(IpfJ%8=k!L4@a~=fKJOqCEWB6lPAF)Dob$DY~72ZZnniIsM z`IY>W)!*B=KJNp9F41fT%+Yo61rzq)z zyjgmPw@Bb}b}R2%9^)O$PSB=)dr}rjB_(rZ7qaF6vgt6=DMmh(AffI-My*3iZADIX zAgO3$Elc~BF{9nU40j{5+d^i$3b2sNwejW4?xLo{)KWqX>$rM{Qw?>Zj+D>U28z%Q znxC6D%tf)~vK8=4COw1B#*L(AwKlFzs- zO3j`nV^_AjG(NZw*Z|B^9%PW~hx%U>DWQRw&4 z?h2k0?frRfv8!anH-vGJ2_s=6Pmhj, Option>); @@ -42,6 +42,7 @@ pub struct Device { modules_runtime: Option, config: DeviceConfig, spaces: Arc>, + selected_space: Option, serial: String, } @@ -81,6 +82,7 @@ impl Device { modules_runtime: None, config: device_conf, spaces, + selected_space: None, serial, }) } @@ -91,8 +93,17 @@ impl Device { if self.modules_runtime.is_none() { self.modules_runtime = Some(Runtime::new().unwrap()); } - for i in 0..self.config.buttons.len() { - let button = self.config.buttons.get(i).unwrap().to_owned(); + // TODO: DO THIS WITHOUT CLONING! Currently takes up a big amount of memory. + let button_config = match &self.selected_space { + Some(s) => self.spaces.get(s).unwrap_or_else(|| { + warn!("The space \"{}\" was not found", s); + &self.config.buttons + } + ).to_owned(), + None => self.config.buttons.to_owned() + }; + for i in 0..button_config.len() { + let button = button_config.get(i).unwrap().to_owned(); unwrap_or_error!(self._create_module(button).await); } } @@ -173,16 +184,16 @@ impl Device { /// Switch to a space. This will tear down the whole runtime of the current space. #[tracing::instrument(skip_all, fields(serial = self.serial))] - async fn switch_to_space(&mut self, name: &String) { + async fn switch_to_space(&mut self, name: String) { debug!("Switching to space {}", name); - self.drop(); - if let Some(space) = self.spaces.get(name) { - self.config.buttons = space.clone(); - self.device.reset().await.unwrap(); - self.init_modules().await; + if name.to_lowercase() == "home" { + self.selected_space = None } else { - error!("Space {} was not found", name); - }; + self.selected_space = Some(name) + } + self.drop(); + self.device.reset().await.unwrap(); + self.init_modules().await; } /// Handle all incoming button state updates from the listener (shell actions, module sender) @@ -219,7 +230,7 @@ impl Device { Some(n) => n.clone(), None => return, }; - self.switch_to_space(&name).await; + self.switch_to_space(name).await; } } } diff --git a/src/modules.rs b/src/modules.rs index fca6ffa..a4db9dd 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -6,17 +6,21 @@ mod space; use self::counter::Counter; use self::space::Space; -use crate::GLOBAL_FONT; // other things +use crate::GLOBAL_FONT; use crate::config::Button; use async_trait::async_trait; pub use deck_driver as streamdeck; use futures_util::Future; -use image::{DynamicImage, Rgb, RgbImage}; +use image::imageops::{resize, self}; +use image::io::Reader; +use image::{DynamicImage, Rgb, RgbImage, ImageBuffer}; use imageproc::drawing::draw_text_mut; +use imageproc::filter; use lazy_static::lazy_static; use rusttype::Scale; use std::collections::HashMap; +use std::io::{BufReader, self}; use std::pin::Pin; use std::str::FromStr; use std::{error::Error, sync::Arc}; @@ -25,7 +29,7 @@ use streamdeck::info::Kind; use streamdeck::AsyncStreamDeck; pub use streamdeck::StreamDeckError; use tokio::sync::mpsc; -use tracing::{debug, error, info}; +use tracing::{debug, error, info, trace}; lazy_static! { static ref MODULE_MAP: HashMap<&'static str, ModuleFunction> = { @@ -114,26 +118,44 @@ impl DeviceAccess { } /// Draw an image with text - /// - /// 60% image - /// 40% text - pub fn image_with_text(&self, image: Vec, text: String, config: &Button) -> DynamicImage { - let res = self.resolution(); - let mut image = RgbImage::new(res.0 as u32, res.1 as u32); + #[tracing::instrument(skip_all, fields(index = config.index))] + pub fn image_with_text(&self, image: DynamicImage, text: String, config: &Button) -> DynamicImage { + trace!("Render start"); + let (w, h) = self.resolution(); + + let image_scaling = parse_config(&config, &"IMAGE_SCALE".into(), 65.0); + + // TODO: lots of parsing. This can probbably be improved. + let new_h = (h as f32 * (image_scaling * 0.01)) as u32; + let new_w = (w as f32 * (image_scaling * 0.01)) as u32; + + // Calculate percentage of which we can scale down to the button resolution. + // By taking the smallest it keeps the aspect ratio. + // let percentage = f32::min(deck_w / image.width() as f32, deck_h / image.height() as f32); + + let image = image.resize_to_fill(new_w, new_h, image::imageops::FilterType::Nearest); + + let mut base_image = RgbImage::new(h as u32, w as u32); draw_text_mut( - &mut image, + &mut base_image, Rgb([255, 255, 255]), - -10, - 10, - Scale::uniform(parse_config(config, &"FONT_SIZE".into(), 20.0)), + 0, + h as i32 - 20, + Scale::uniform(parse_config(config, &"FONT_SIZE".into(), 15.0)), &GLOBAL_FONT.get().unwrap(), &text, ); - image::DynamicImage::ImageRgb8(image) + // position at the middle + let free_space = w - image.width() as usize; + imageops::overlay(&mut base_image, &image.to_rgb8(), (free_space/2) as i64, 0); + trace!("Render end"); + image::DynamicImage::ImageRgb8(base_image) } /// Draw text + #[tracing::instrument(skip_all, fields(index = config.index))] pub fn text(&self, text: String, config: &Button) -> DynamicImage { + trace!("Render start"); let res = self.resolution(); let mut image = RgbImage::new(res.0 as u32, res.1 as u32); draw_text_mut( @@ -141,16 +163,41 @@ impl DeviceAccess { Rgb([255, 255, 255]), 10, 10, - Scale::uniform(parse_config(config, &"FONT_SIZE".into(), 20.0)), + Scale::uniform(parse_config(config, &"FONT_SIZE".into(), 15.0)), &GLOBAL_FONT.get().unwrap(), &text, ); + trace!("Render end"); image::DynamicImage::ImageRgb8(image) } } +/// Loads the image from the `IMAGE` option. +/// Displays [create_error_image] if it does not exist or cannot be loeded. +pub fn load_image(config: &Button) -> io::Result { + // TODO: maybe us an Option (faster?) + let file_path = parse_config(config, &"IMAGE".into(), "None".to_string()); + + if file_path == "None" { + return Ok(create_error_image()); + } + + Ok(Reader::open(file_path)?.decode().expect("Unable to decode image")) +} + +/// A smooth red image which should represent an empty space +pub fn create_error_image() -> DynamicImage { + let mut error_img: RgbImage = ImageBuffer::new(1, 1); + + for pixel in error_img.enumerate_pixels_mut() { + *pixel.2 = image::Rgb([240, 128, 128]); + } + + DynamicImage::ImageRgb8(error_img) +} + /// reads a key from the config and parses the config in the given type -fn parse_config(config: &Button, key: &String, if_wrong_type: T) -> T +pub fn parse_config(config: &Button, key: &String, if_wrong_type: T) -> T where T: FromStr, { diff --git a/src/modules/space.rs b/src/modules/space.rs index 2b9a02c..f909802 100644 --- a/src/modules/space.rs +++ b/src/modules/space.rs @@ -3,6 +3,9 @@ use super::ChannelReceiver; use super::DeviceAccess; use super::Module; use super::ReturnError; +use super::create_error_image; +use super::load_image; +use super::parse_config; use async_trait::async_trait; use std::sync::Arc; @@ -12,10 +15,16 @@ pub struct Space; #[async_trait] impl Module for Space { async fn run( - _streamdeck: DeviceAccess, + streamdeck: DeviceAccess, _button_receiver: ChannelReceiver, - _config: Arc