Compare commits
No commits in common. "822d4706054b29d994c31259431eb11d7172fffb" and "86e9b072bcb5bb9e0ee52df1d1a30e048084b9c7" have entirely different histories.
822d470605
...
86e9b072bc
@ -122,36 +122,8 @@ impl ConfigManager {
|
|||||||
log::info!("mapper: {:?}", mapper);
|
log::info!("mapper: {:?}", mapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let cloned_config = config.clone();
|
Self::rebuild_mappers(&mut config);
|
||||||
|
|
||||||
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();
|
let cloned_config = config.clone();
|
||||||
|
|
||||||
|
@ -175,18 +175,6 @@ 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]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
@ -209,7 +197,6 @@ async fn main() {
|
|||||||
patch_led_strip_len,
|
patch_led_strip_len,
|
||||||
send_colors,
|
send_colors,
|
||||||
move_strip_part,
|
move_strip_part,
|
||||||
reverse_led_strip_part,
|
|
||||||
])
|
])
|
||||||
.register_uri_scheme_protocol("ambient-light", move |_app, request| {
|
.register_uri_scheme_protocol("ambient-light", move |_app, request| {
|
||||||
let response = ResponseBuilder::new().header("Access-Control-Allow-Origin", "*");
|
let response = ResponseBuilder::new().header("Access-Control-Allow-Origin", "*");
|
||||||
|
@ -4,13 +4,13 @@ use core_graphics::display::{
|
|||||||
kCGNullWindowID, kCGWindowImageDefault, kCGWindowListOptionOnScreenOnly, CGDisplay,
|
kCGNullWindowID, kCGWindowImageDefault, kCGWindowListOptionOnScreenOnly, CGDisplay,
|
||||||
};
|
};
|
||||||
use paris::{error, info, warn};
|
use paris::{error, info, warn};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use tauri::{async_runtime::RwLock, Window};
|
use tauri::{async_runtime::RwLock, Window};
|
||||||
use tokio::sync::{watch, OnceCell};
|
use tokio::sync::{watch, OnceCell};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ambient_light::{SamplePointConfig, SamplePointMapper},
|
ambient_light::{SamplePointConfig, SamplePointMapper},
|
||||||
led_color::LedColor,
|
screenshot::{LedSamplePoints, ScreenSamplePoints, Screenshot, ScreenshotPayload}, led_color::LedColor,
|
||||||
screenshot::{ScreenSamplePoints, Screenshot, ScreenshotPayload},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn take_screenshot(display_id: u32, scale_factor: f32) -> anyhow::Result<Screenshot> {
|
pub fn take_screenshot(display_id: u32, scale_factor: f32) -> anyhow::Result<Screenshot> {
|
||||||
@ -220,6 +220,7 @@ impl ScreenshotManager {
|
|||||||
configs: &Vec<SamplePointConfig>,
|
configs: &Vec<SamplePointConfig>,
|
||||||
screenshots: &Vec<Screenshot>,
|
screenshots: &Vec<Screenshot>,
|
||||||
) -> Vec<LedColor> {
|
) -> Vec<LedColor> {
|
||||||
|
|
||||||
let mut all_colors = vec![];
|
let mut all_colors = vec![];
|
||||||
|
|
||||||
for (index, screenshot) in screenshots.iter().enumerate() {
|
for (index, screenshot) in screenshots.iter().enumerate() {
|
||||||
@ -232,10 +233,7 @@ impl ScreenshotManager {
|
|||||||
all_colors
|
all_colors
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_sorted_colors(
|
pub async fn get_sorted_colors(colors: &Vec<LedColor>, mappers: &Vec<SamplePointMapper>) -> Vec<u8> {
|
||||||
colors: &Vec<LedColor>,
|
|
||||||
mappers: &Vec<SamplePointMapper>,
|
|
||||||
) -> Vec<u8> {
|
|
||||||
let total_leds = mappers
|
let total_leds = mappers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|mapper| usize::max(mapper.start, mapper.end))
|
.map(|mapper| usize::max(mapper.start, mapper.end))
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
batch,
|
|
||||||
Component,
|
Component,
|
||||||
createContext,
|
createContext,
|
||||||
createEffect,
|
createEffect,
|
||||||
createMemo,
|
createMemo,
|
||||||
createSignal,
|
createSignal,
|
||||||
For,
|
For,
|
||||||
Index,
|
|
||||||
JSX,
|
JSX,
|
||||||
on,
|
|
||||||
untrack,
|
|
||||||
useContext,
|
useContext,
|
||||||
} from 'solid-js';
|
} from 'solid-js';
|
||||||
import { LedStripConfig, LedStripPixelMapper } from '../models/led-strip-config';
|
import { LedStripConfig, LedStripPixelMapper } from '../models/led-strip-config';
|
||||||
@ -26,13 +22,13 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
|
|||||||
const [dragStart, setDragStart] = createSignal<{ x: number; y: number } | null>(null);
|
const [dragStart, setDragStart] = createSignal<{ x: number; y: number } | null>(null);
|
||||||
const [dragCurr, setDragCurr] = createSignal<{ x: number; y: number } | null>(null);
|
const [dragCurr, setDragCurr] = createSignal<{ x: number; y: number } | null>(null);
|
||||||
const [dragStartIndex, setDragStartIndex] = createSignal<number>(0);
|
const [dragStartIndex, setDragStartIndex] = createSignal<number>(0);
|
||||||
const [cellWidth, setCellWidth] = createSignal<number>(0);
|
|
||||||
const [, { setSelectedStripPart }] = useContext(LedStripConfigurationContext);
|
const [, { setSelectedStripPart }] = useContext(LedStripConfigurationContext);
|
||||||
|
|
||||||
const move = (targetStart: number) => {
|
const move = (targetStart: number) => {
|
||||||
if (targetStart === props.mapper.start) {
|
if (targetStart === props.mapper.start) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log(`target_start ${targetStart}`);
|
||||||
invoke('move_strip_part', {
|
invoke('move_strip_part', {
|
||||||
displayId: props.strip.display_id,
|
displayId: props.strip.display_id,
|
||||||
border: props.strip.border,
|
border: props.strip.border,
|
||||||
@ -40,25 +36,6 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
|
|||||||
}).catch((err) => console.error(err));
|
}).catch((err) => console.error(err));
|
||||||
};
|
};
|
||||||
|
|
||||||
// reset translateX on config updated
|
|
||||||
createEffect(() => {
|
|
||||||
const indexDiff = props.mapper.start - dragStartIndex();
|
|
||||||
untrack(() => {
|
|
||||||
if (!dragStart() || !dragCurr()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const compensation = indexDiff * cellWidth();
|
|
||||||
batch(() => {
|
|
||||||
setDragStartIndex(props.mapper.start);
|
|
||||||
setDragStart({
|
|
||||||
x: dragStart()!.x + compensation,
|
|
||||||
y: dragCurr()!.y,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const onPointerDown = (ev: PointerEvent) => {
|
const onPointerDown = (ev: PointerEvent) => {
|
||||||
if (ev.button !== 0) {
|
if (ev.button !== 0) {
|
||||||
return;
|
return;
|
||||||
@ -97,7 +74,6 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
|
|||||||
if (moved === 0) {
|
if (moved === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setCellWidth(cellWidth);
|
|
||||||
move(props.mapper.start + moved);
|
move(props.mapper.start + moved);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,43 +81,17 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
|
|||||||
setSelectedStripPart(null);
|
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
|
// update fullLeds
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const fullLeds = new Array(ledStripStore.totalLedCount).fill(null);
|
const fullLeds = new Array(ledStripStore.totalLedCount).fill(null);
|
||||||
|
|
||||||
// if (props.mapper.start < props.mapper.end) {
|
for (
|
||||||
// for (
|
let i = props.mapper.start, j = props.mapper.pos;
|
||||||
// let i = props.mapper.start, j = props.mapper.pos;
|
i < props.mapper.end;
|
||||||
// i < props.mapper.end;
|
i++, j++
|
||||||
// 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];
|
fullLeds[i] = ledStripStore.colors[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
setFullLeds(fullLeds);
|
setFullLeds(fullLeds);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -159,7 +109,6 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
|
|||||||
onPointerDown={onPointerDown}
|
onPointerDown={onPointerDown}
|
||||||
onPointerUp={onPointerUp}
|
onPointerUp={onPointerUp}
|
||||||
onPointerLeave={onPointerLeave}
|
onPointerLeave={onPointerLeave}
|
||||||
ondblclick={reverse}
|
|
||||||
>
|
>
|
||||||
<For each={fullLeds()}>
|
<For each={fullLeds()}>
|
||||||
{(it) => (
|
{(it) => (
|
||||||
@ -183,20 +132,15 @@ const SorterResult: Component = () => {
|
|||||||
const [fullLeds, setFullLeds] = createSignal<string[]>([]);
|
const [fullLeds, setFullLeds] = createSignal<string[]>([]);
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const colors = ledStripStore.sortedColors;
|
const fullLeds = new Array(ledStripStore.totalLedCount).fill('rgba(255,255,255,0.1)');
|
||||||
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)})`;
|
|
||||||
|
|
||||||
return `linear-gradient(70deg, ${c1}, ${c2})`;
|
ledStripStore.mappers.forEach((mapper) => {
|
||||||
});
|
for (let i = mapper.start, j = 0; i < mapper.end; i++, j++) {
|
||||||
console.log(fullLeds);
|
fullLeds[i] = `rgb(${ledStripStore.sortedColors[i * 3]}, ${
|
||||||
|
ledStripStore.sortedColors[i * 3 + 1]
|
||||||
|
}, ${ledStripStore.sortedColors[i * 3 + 2]})`;
|
||||||
|
}
|
||||||
|
});
|
||||||
setFullLeds(fullLeds);
|
setFullLeds(fullLeds);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -230,11 +174,11 @@ export const LedStripPartsSorter: Component = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SorterResult />
|
<SorterResult />
|
||||||
<Index each={ledStripStore.strips}>
|
<For each={ledStripStore.strips}>
|
||||||
{(strip, index) => (
|
{(strip, index) => (
|
||||||
<SorterItem strip={strip()} mapper={ledStripStore.mappers[index]} />
|
<SorterItem strip={strip} mapper={ledStripStore.mappers[index()]} />
|
||||||
)}
|
)}
|
||||||
</Index>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
8
src/models/picker-configuration.ts
Normal file
8
src/models/picker-configuration.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { DisplayConfig } from './display-config';
|
||||||
|
|
||||||
|
export class PickerConfiguration {
|
||||||
|
constructor(
|
||||||
|
public display_configs: DisplayConfig[] = [],
|
||||||
|
public config_version: number = 1,
|
||||||
|
) {}
|
||||||
|
}
|
12
src/models/screenshot.dto.ts
Normal file
12
src/models/screenshot.dto.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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