commit
This commit is contained in:
parent
102de5504b
commit
97cdbdea1c
5 changed files with 58 additions and 8 deletions
|
@ -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}%"
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue