This commit is contained in:
Moritz Ruth 2024-01-11 20:48:11 +01:00
parent 102de5504b
commit 97cdbdea1c
Signed by: moritzruth
GPG key ID: C9BBAB79405EE56D
5 changed files with 58 additions and 8 deletions

View file

@ -1,8 +1,8 @@
[knobs.right-top]
icon = "@ph/microphone-light[scale=0.9]"
indicator.circle.color = "#ffffff"
indicator.circle.width = 2
indicator.circle.radius = 40
indicators.circle.color = "#ffffff"
indicators.circle.width = 2
indicators.circle.radius = 20
mode.audio_volume.direction = "input"
mode.audio_volume.regex = "Microphone"
@ -13,7 +13,7 @@ mode.audio_volume.style.inactive.icon = "@ph/microphone-slash-light[alpha=0.9|co
[knobs.right-middle]
icon = "@apps/discord[scale=0.25]"
indicator.bar.color = "#ffffff"
indicators.bar.color = "#ffffff"
mode.audio_volume.regex = "Discord"
mode.audio_volume.style.active.label = "{percentage}%"
@ -23,7 +23,7 @@ mode.audio_volume.style.inactive.icon = "@apps/discord[grayscale|alpha=0.9]"
[knobs.right-bottom]
icon = "@apps/spotify[scale=1.1]"
indicator.bar.color = "#ffffff"
indicators.bar.color = "#ffffff50"
mode.audio_volume.regex = "Spotify"
mode.audio_volume.style.active.label = "{percentage}%"

View file

@ -7,11 +7,13 @@ use tokio::sync::broadcast;
use crate::model::knob_page::StyleByStateMap;
use crate::model::position::KnobPath;
use crate::modes::knob::KnobEvent;
use crate::modes::knob::{KnobEvent, RotationDirection};
use crate::runner::command::IoWorkerCommand;
#[derive(Debug, Deserialize)]
pub struct Config {
#[serde(default = "default_delta")]
pub delta: f32,
#[serde(with = "serde_regex")]
pub regex: Regex,
#[serde(default)]
@ -28,6 +30,10 @@ pub struct Config {
pub style: StyleByStateMap<State>,
}
fn default_delta() -> f32 {
0.05
}
#[derive(Debug, Default, Eq, PartialEq, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum MutedTurnAction {
@ -54,11 +60,22 @@ pub enum State {
}
pub async fn handle(path: KnobPath, config: Arc<Config>, mut events: broadcast::Receiver<(KnobPath, KnobEvent)>, commands: flume::Sender<IoWorkerCommand>) {
let mut value: f32 = 0.0;
while let Ok((event_path, event)) = events.recv().await {
if event_path != path {
continue;
}
dbg!(path.clone(), event);
if let KnobEvent::Rotate { direction } = event {
let factor = match direction {
RotationDirection::Clockwise => 1.0,
RotationDirection::Counterclockwise => -1.0,
};
value = (value + (factor * config.delta)).clamp(0.0, 1.0);
commands.send(IoWorkerCommand::SetKnobValue { path: path.clone(), value }).unwrap();
}
}
}

View file

@ -12,4 +12,5 @@ pub enum IoWorkerCommand {
SetActivePages { key_page_id: String, knob_page_id: String },
SetKeyStyle { path: KeyPath, value: Option<KeyStyle> },
SetKnobStyle { path: KnobPath, value: Option<KnobStyle> },
SetKnobValue { path: KnobPath, value: f32 },
}

View file

@ -3,6 +3,7 @@ use std::collections::HashMap;
use bytes::{BufMut, Bytes, BytesMut};
use resvg::usvg::tiny_skia_path::PathBuilder;
use rgb::RGBA;
use tiny_skia::{Color, IntSize, LineCap, LineJoin, Paint, Pixmap, PremultipliedColorU8, Rect, Shader, Stroke, Transform};
use loupedeck_serial::util::Endianness;
@ -76,6 +77,26 @@ pub fn render_knob(context: &GraphicsContext, screen_size: IntSize, state: Optio
context.label_renderer.borrow_mut().render(&mut pixmap, label);
}
}
if let Some(indicators) = &style.indicators {
if let Some(bar) = indicators.bar.as_ref() {
let color = bar.color.unwrap_or(RGBA::new(0xff, 0xff, 0xff, 0x50).into());
const PADDING: f32 = 20.0;
let max_height: f32 = pixmap.height() as f32 - PADDING * 2.0;
let height = state.value * max_height;
let y = pixmap.height() as f32 - PADDING - height;
pixmap.fill_rect(
Rect::from_xywh(pixmap.width() as f32 - 10.0, y, 5.0, height).unwrap(),
&Paint {
shader: Shader::SolidColor(Color::from_rgba8(color.r, color.g, color.b, color.a)),
..Paint::default()
},
Transform::identity(),
None,
);
}
}
}
convert_pixels_to_rgb565(pixmap.pixels(), context.buffer_endianness).freeze()

View file

@ -7,7 +7,7 @@ use std::time::Instant;
use color_eyre::eyre::{ContextCompat, WrapErr};
use color_eyre::Result;
use enum_ordinalize::Ordinalize;
use log::{info, trace};
use log::{error, info, trace};
use rgb::RGB8;
use tiny_skia::IntSize;
use tokio::sync::broadcast;
@ -341,6 +341,17 @@ fn handle_command(context: &IoWorkerContext, state: &mut State, command: IoWorke
draw_knob_at_path_if_visible(context, state, path);
context.device.refresh_display(&context.device.characteristics().key_grid.display).unwrap();
}
IoWorkerCommand::SetKnobValue { path, value } => {
if !(0.0..=1.0).contains(&value) {
error!("Received SetKnobValue with an out-of-range value: {}", value)
} else {
state.mutate_knob_for_command("SetKnobValue", &path, |k| {
k.value = value;
});
draw_knob_at_path_if_visible(context, state, path);
}
}
}
}