feat: 支持翻转灯条段。
This commit is contained in:
parent
fa5e27f72a
commit
822d470605
@ -123,7 +123,35 @@ impl ConfigManager {
|
||||
}
|
||||
}
|
||||
|
||||
Self::rebuild_mappers(&mut config);
|
||||
let cloned_config = config.clone();
|
||||
|
||||
drop(config);
|
||||
|
||||
self.update(&cloned_config).await?;
|
||||
|
||||
self.config_update_sender
|
||||
.send(cloned_config)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to send config update: {}", e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn reverse_led_strip_part(
|
||||
&self,
|
||||
display_id: u32,
|
||||
border: Border,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut config = self.config.write().await;
|
||||
|
||||
for (index, strip) in config.clone().strips.iter().enumerate() {
|
||||
if strip.display_id == display_id && strip.border == border {
|
||||
let mut mapper = config.mappers[index].borrow_mut();
|
||||
|
||||
let start = mapper.start;
|
||||
mapper.start = mapper.end;
|
||||
mapper.end = start;
|
||||
}
|
||||
}
|
||||
|
||||
let cloned_config = config.clone();
|
||||
|
||||
|
@ -175,6 +175,18 @@ async fn move_strip_part(display_id: u32, border: Border, target_start: usize) -
|
||||
})
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn reverse_led_strip_part(display_id: u32, border: Border) -> Result<(), String> {
|
||||
let config_manager = ambient_light::ConfigManager::global().await;
|
||||
config_manager
|
||||
.reverse_led_strip_part(display_id, border)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("can not reverse led strip part: {}", e);
|
||||
e.to_string()
|
||||
})
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
env_logger::init();
|
||||
@ -197,6 +209,7 @@ async fn main() {
|
||||
patch_led_strip_len,
|
||||
send_colors,
|
||||
move_strip_part,
|
||||
reverse_led_strip_part,
|
||||
])
|
||||
.register_uri_scheme_protocol("ambient-light", move |_app, request| {
|
||||
let response = ResponseBuilder::new().header("Access-Control-Allow-Origin", "*");
|
||||
|
@ -4,13 +4,13 @@ use core_graphics::display::{
|
||||
kCGNullWindowID, kCGWindowImageDefault, kCGWindowListOptionOnScreenOnly, CGDisplay,
|
||||
};
|
||||
use paris::{error, info, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{async_runtime::RwLock, Window};
|
||||
use tokio::sync::{watch, OnceCell};
|
||||
|
||||
use crate::{
|
||||
ambient_light::{SamplePointConfig, SamplePointMapper},
|
||||
screenshot::{LedSamplePoints, ScreenSamplePoints, Screenshot, ScreenshotPayload}, led_color::LedColor,
|
||||
led_color::LedColor,
|
||||
screenshot::{ScreenSamplePoints, Screenshot, ScreenshotPayload},
|
||||
};
|
||||
|
||||
pub fn take_screenshot(display_id: u32, scale_factor: f32) -> anyhow::Result<Screenshot> {
|
||||
@ -220,7 +220,6 @@ impl ScreenshotManager {
|
||||
configs: &Vec<SamplePointConfig>,
|
||||
screenshots: &Vec<Screenshot>,
|
||||
) -> Vec<LedColor> {
|
||||
|
||||
let mut all_colors = vec![];
|
||||
|
||||
for (index, screenshot) in screenshots.iter().enumerate() {
|
||||
@ -233,7 +232,10 @@ impl ScreenshotManager {
|
||||
all_colors
|
||||
}
|
||||
|
||||
pub async fn get_sorted_colors(colors: &Vec<LedColor>, mappers: &Vec<SamplePointMapper>) -> Vec<u8> {
|
||||
pub async fn get_sorted_colors(
|
||||
colors: &Vec<LedColor>,
|
||||
mappers: &Vec<SamplePointMapper>,
|
||||
) -> Vec<u8> {
|
||||
let total_leds = mappers
|
||||
.iter()
|
||||
.map(|mapper| usize::max(mapper.start, mapper.end))
|
||||
|
@ -105,17 +105,43 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
|
||||
setSelectedStripPart(null);
|
||||
};
|
||||
|
||||
const reverse = () => {
|
||||
invoke('reverse_led_strip_part', {
|
||||
displayId: props.strip.display_id,
|
||||
border: props.strip.border,
|
||||
}).catch((err) => console.error(err));
|
||||
};
|
||||
|
||||
// update fullLeds
|
||||
createEffect(() => {
|
||||
const fullLeds = new Array(ledStripStore.totalLedCount).fill(null);
|
||||
|
||||
for (
|
||||
let i = props.mapper.start, j = props.mapper.pos;
|
||||
i < props.mapper.end;
|
||||
i++, j++
|
||||
) {
|
||||
// if (props.mapper.start < props.mapper.end) {
|
||||
// for (
|
||||
// let i = props.mapper.start, j = props.mapper.pos;
|
||||
// i < props.mapper.end;
|
||||
// i++, j++
|
||||
// ) {
|
||||
// fullLeds[i] = ledStripStore.colors[j];
|
||||
// }
|
||||
// } else {
|
||||
// for (
|
||||
// let i = props.mapper.start, j = props.mapper.pos;
|
||||
// i >= props.mapper.end;
|
||||
// i--, j++
|
||||
// ) {
|
||||
// fullLeds[i] = ledStripStore.colors[j];
|
||||
// }
|
||||
// }
|
||||
// 优化上面的代码
|
||||
|
||||
const { start, end, pos } = props.mapper;
|
||||
const isForward = start < end;
|
||||
const step = isForward ? 1 : -1;
|
||||
for (let i = start, j = pos; i !== end; i += step, j++) {
|
||||
fullLeds[i] = ledStripStore.colors[j];
|
||||
}
|
||||
|
||||
setFullLeds(fullLeds);
|
||||
});
|
||||
|
||||
@ -133,6 +159,7 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
|
||||
onPointerDown={onPointerDown}
|
||||
onPointerUp={onPointerUp}
|
||||
onPointerLeave={onPointerLeave}
|
||||
ondblclick={reverse}
|
||||
>
|
||||
<For each={fullLeds()}>
|
||||
{(it) => (
|
||||
@ -156,15 +183,20 @@ const SorterResult: Component = () => {
|
||||
const [fullLeds, setFullLeds] = createSignal<string[]>([]);
|
||||
|
||||
createEffect(() => {
|
||||
const fullLeds = new Array(ledStripStore.totalLedCount).fill('rgba(255,255,255,0.1)');
|
||||
const colors = ledStripStore.sortedColors;
|
||||
const fullLeds = new Array(ledStripStore.totalLedCount)
|
||||
.fill('rgba(255,255,255,0.1)')
|
||||
.map((_, i) => {
|
||||
let c1 = `rgb(${Math.floor(colors[i * 3] * 0.8)}, ${Math.floor(
|
||||
colors[i * 3 + 1] * 0.8,
|
||||
)}, ${Math.floor(colors[i * 3 + 2] * 0.8)})`;
|
||||
let c2 = `rgb(${Math.floor(colors[i * 3] * 1.2)}, ${Math.floor(
|
||||
colors[i * 3 + 1] * 1.2,
|
||||
)}, ${Math.floor(colors[i * 3 + 2] * 1.2)})`;
|
||||
|
||||
ledStripStore.mappers.forEach((mapper) => {
|
||||
for (let i = mapper.start, j = 0; i < mapper.end; i++, j++) {
|
||||
fullLeds[i] = `rgb(${ledStripStore.sortedColors[i * 3]}, ${
|
||||
ledStripStore.sortedColors[i * 3 + 1]
|
||||
}, ${ledStripStore.sortedColors[i * 3 + 2]})`;
|
||||
}
|
||||
return `linear-gradient(70deg, ${c1}, ${c2})`;
|
||||
});
|
||||
console.log(fullLeds);
|
||||
setFullLeds(fullLeds);
|
||||
});
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
import { DisplayConfig } from './display-config';
|
||||
|
||||
export class PickerConfiguration {
|
||||
constructor(
|
||||
public display_configs: DisplayConfig[] = [],
|
||||
public config_version: number = 1,
|
||||
) {}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { DisplayConfig } from './display-config';
|
||||
|
||||
export class ScreenshotDto {
|
||||
encode_image!: string;
|
||||
config!: DisplayConfig;
|
||||
colors!: {
|
||||
top: Uint8Array;
|
||||
bottom: Uint8Array;
|
||||
left: Uint8Array;
|
||||
right: Uint8Array;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user