platform::timeline
This commit is contained in:
parent
6c4845b81d
commit
a37675b094
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1538,9 +1538,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -1568,9 +1568,9 @@ checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
|||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -4124,6 +4124,8 @@ dependencies = [
|
|||
name = "shared"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"moonlight",
|
||||
"wellen",
|
||||
]
|
||||
|
||||
|
|
|
@ -16,11 +16,12 @@ readme = "../README.md"
|
|||
publish = false
|
||||
|
||||
[workspace.dependencies]
|
||||
shared = { path = "./shared" }
|
||||
# wellen = { version = "0.9.9", features = ["serde1"] }
|
||||
# wellen = { path = "../wellen/wellen", features = ["serde1"] }
|
||||
wellen = { git = "https://github.com/MartinKavik/wellen", features = ["serde1"], branch = "new_pub_types" }
|
||||
# moon = { path = "../../crates/moon" }
|
||||
# zoon = { path = "../../crates/zoon" }
|
||||
# moonlight = { path = "../../crates/zoon" }
|
||||
zoon = { git = "https://github.com/MoonZoon/MoonZoon", rev = "fc73b0d90bf39be72e70fdcab4f319ea5b8e6cfc" }
|
||||
moon = { git = "https://github.com/MoonZoon/MoonZoon", rev = "fc73b0d90bf39be72e70fdcab4f319ea5b8e6cfc" }
|
||||
moonlight = { git = "https://github.com/MoonZoon/MoonZoon", rev = "fc73b0d90bf39be72e70fdcab4f319ea5b8e6cfc" }
|
||||
|
|
|
@ -11,8 +11,8 @@ publish.workspace = true
|
|||
wasm-bindgen-test = "0.3.19"
|
||||
|
||||
[dependencies]
|
||||
shared.workspace = true
|
||||
zoon.workspace = true
|
||||
wellen.workspace = true
|
||||
shared = { path = "../shared", features = ["frontend"] }
|
||||
web-sys = { version = "*", features = ["FileSystemFileHandle"] }
|
||||
gloo-file = { version = "0.3.0", features = ["futures"] }
|
||||
|
|
|
@ -37,6 +37,10 @@ pub async fn load_and_get_signal(signal_ref: wellen::SignalRef) -> wellen::Signa
|
|||
platform::load_and_get_signal(signal_ref).await
|
||||
}
|
||||
|
||||
pub async fn timeline(signal_ref: wellen::SignalRef, screen_width: u32) -> shared::Timeline {
|
||||
platform::timeline(signal_ref, screen_width).await
|
||||
}
|
||||
|
||||
pub async fn unload_signal(signal_ref: wellen::SignalRef) {
|
||||
platform::unload_signal(signal_ref).await
|
||||
}
|
||||
|
|
|
@ -91,6 +91,10 @@ pub(super) async fn load_and_get_signal(signal_ref: wellen::SignalRef) -> wellen
|
|||
serde_json::from_value(serde_json::to_value(signal).unwrap_throw()).unwrap_throw()
|
||||
}
|
||||
|
||||
pub(super) async fn timeline(signal_ref: wellen::SignalRef, screen_width: u32) -> shared::Timeline {
|
||||
shared::Timeline { blocks: Vec::new() }
|
||||
}
|
||||
|
||||
pub(super) async fn unload_signal(signal_ref: wellen::SignalRef) {
|
||||
let mut waveform_lock = STORE.waveform.lock().unwrap_throw();
|
||||
let waveform = waveform_lock.as_mut().unwrap_throw();
|
||||
|
|
|
@ -30,6 +30,15 @@ pub(super) async fn load_and_get_signal(signal_ref: wellen::SignalRef) -> wellen
|
|||
.unwrap_throw()
|
||||
}
|
||||
|
||||
pub(super) async fn timeline(signal_ref: wellen::SignalRef, screen_width: u32) -> shared::Timeline {
|
||||
serde_wasm_bindgen::from_value(
|
||||
tauri_glue::timeline(signal_ref.index(), screen_width)
|
||||
.await
|
||||
.unwrap_throw(),
|
||||
)
|
||||
.unwrap_throw()
|
||||
}
|
||||
|
||||
pub(super) async fn unload_signal(signal_ref: wellen::SignalRef) {
|
||||
tauri_glue::unload_signal(signal_ref.index())
|
||||
.await
|
||||
|
@ -57,6 +66,9 @@ mod tauri_glue {
|
|||
#[wasm_bindgen(catch)]
|
||||
pub async fn load_and_get_signal(signal_ref_index: usize) -> Result<JsValue, JsValue>;
|
||||
|
||||
#[wasm_bindgen(catch)]
|
||||
pub async fn timeline(signal_ref_index: usize, screen_width: u32) -> Result<JsValue, JsValue>;
|
||||
|
||||
#[wasm_bindgen(catch)]
|
||||
pub async fn unload_signal(signal_ref_index: usize) -> Result<(), JsValue>;
|
||||
}
|
||||
|
|
|
@ -117,24 +117,19 @@ impl WaveformPanel {
|
|||
|
||||
let var = hierarchy.get(var_ref);
|
||||
let signal_ref = var.signal_ref();
|
||||
let signal = platform::load_and_get_signal(signal_ref).await;
|
||||
let timeline = platform::timeline(signal_ref, controller.screen_width()).await;
|
||||
|
||||
// @TODO remove
|
||||
zoon::println!("Timeline in Rust: {timeline:#?}");
|
||||
|
||||
let timescale = hierarchy.timescale();
|
||||
// @TODO remove
|
||||
zoon::println!("{timescale:?}");
|
||||
|
||||
let mut timeline: Vec<(wellen::Time, String)> = signal
|
||||
.iter_changes()
|
||||
.map(|(time_index, signal_value)| {
|
||||
(time_table[time_index as usize], signal_value.to_string())
|
||||
})
|
||||
.collect();
|
||||
if timeline.is_empty() {
|
||||
if timeline.blocks.is_empty() {
|
||||
eprintln!("timeline is empty");
|
||||
return;
|
||||
}
|
||||
timeline.push((last_time, timeline.last().cloned().unwrap_throw().1));
|
||||
|
||||
// Note: Sync `timeline`'s type with the `Timeline` in `frontend/typescript/pixi_canvas/pixi_canvas.ts'
|
||||
controller.push_var(serde_wasm_bindgen::to_value(&timeline).unwrap_throw());
|
||||
}
|
||||
|
|
|
@ -100,11 +100,14 @@ mod js_bridge {
|
|||
#[wasm_bindgen(method)]
|
||||
pub async fn init(this: &PixiController, parent_element: &JsValue);
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
pub fn queue_resize(this: &PixiController);
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
pub fn destroy(this: &PixiController);
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
pub fn queue_resize(this: &PixiController);
|
||||
pub fn screen_width(this: &PixiController) -> u32;
|
||||
|
||||
// -- FastWave-specific --
|
||||
|
||||
|
|
|
@ -35126,7 +35126,6 @@ var import_earcut2 = __toESM(require_earcut(), 1);
|
|||
extensions.add(browserExt, webworkerExt);
|
||||
|
||||
// pixi_canvas.ts
|
||||
var MIN_BLOCK_WIDTH = 1;
|
||||
var PixiController = class {
|
||||
app;
|
||||
// -- FastWave-specific --
|
||||
|
@ -35160,6 +35159,9 @@ var PixiController = class {
|
|||
};
|
||||
this.app.destroy(rendererDestroyOptions, options);
|
||||
}
|
||||
screen_width() {
|
||||
return this.app.screen.width;
|
||||
}
|
||||
// -- FastWave-specific --
|
||||
remove_var(index) {
|
||||
if (typeof this.var_signal_rows[index] !== "undefined") {
|
||||
|
@ -35167,6 +35169,7 @@ var PixiController = class {
|
|||
}
|
||||
}
|
||||
push_var(timeline) {
|
||||
console.log("Timline in Typescript:", timeline);
|
||||
new VarSignalRow(
|
||||
timeline,
|
||||
this.app,
|
||||
|
@ -35186,17 +35189,13 @@ var PixiController = class {
|
|||
var VarSignalRow = class {
|
||||
app;
|
||||
timeline;
|
||||
last_time;
|
||||
formatter;
|
||||
timeline_for_ui;
|
||||
owner;
|
||||
index_in_owner;
|
||||
rows_container;
|
||||
row_height;
|
||||
row_gap;
|
||||
row_height_with_gap;
|
||||
renderer_resize_callback = () => this.redraw_on_canvas_resize();
|
||||
// -- elements --
|
||||
renderer_resize_callback = () => this.draw();
|
||||
row_container = new Container();
|
||||
signal_blocks_container = new Container();
|
||||
label_style = new TextStyle({
|
||||
|
@ -35208,12 +35207,6 @@ var VarSignalRow = class {
|
|||
constructor(timeline, app, owner, rows_container, row_height, row_gap) {
|
||||
this.app = app;
|
||||
this.timeline = timeline;
|
||||
this.last_time = timeline[timeline.length - 1][0];
|
||||
this.formatter = (signal_value) => parseInt(signal_value, 2).toString(16);
|
||||
this.timeline_for_ui = this.timeline.map(([time, value]) => {
|
||||
const x2 = time / this.last_time * this.app.screen.width;
|
||||
return [x2, this.formatter(value)];
|
||||
});
|
||||
this.row_height = row_height;
|
||||
this.row_gap = row_gap;
|
||||
this.row_height_with_gap = row_height + row_gap;
|
||||
|
@ -35221,90 +35214,26 @@ var VarSignalRow = class {
|
|||
this.owner = owner;
|
||||
this.owner.push(this);
|
||||
this.rows_container = rows_container;
|
||||
this.draw();
|
||||
this.app.renderer.on("resize", this.renderer_resize_callback);
|
||||
}
|
||||
async draw() {
|
||||
this.row_container.y = this.index_in_owner * this.row_height_with_gap;
|
||||
this.rows_container.addChild(this.row_container);
|
||||
this.row_container.addChild(this.signal_blocks_container);
|
||||
for (let index = 0; index < this.timeline_for_ui.length; index++) {
|
||||
if (index == this.timeline_for_ui.length - 1) {
|
||||
return;
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
const [x2, value] = this.timeline_for_ui[index];
|
||||
const block_width = this.timeline_for_ui[index + 1][0] - x2;
|
||||
const block_height = this.row_height;
|
||||
if (block_width < MIN_BLOCK_WIDTH) {
|
||||
return;
|
||||
}
|
||||
const signal_block = new Container();
|
||||
signal_block.x = x2;
|
||||
this.signal_blocks_container.addChild(signal_block);
|
||||
const background = new Graphics().roundRect(0, 0, block_width, block_height, 15).fill("SlateBlue");
|
||||
background.label = "background";
|
||||
signal_block.addChild(background);
|
||||
const label = new Text({ text: value, style: this.label_style });
|
||||
label.x = (block_width - label.width) / 2;
|
||||
label.y = (block_height - label.height) / 2;
|
||||
label.visible = label.width < block_width;
|
||||
label.label = "label";
|
||||
signal_block.addChild(label);
|
||||
}
|
||||
this.draw();
|
||||
}
|
||||
async redraw_on_canvas_resize() {
|
||||
for (let index = 0; index < this.timeline_for_ui.length; index++) {
|
||||
const x2 = this.timeline[index][0] / this.last_time * this.app.screen.width;
|
||||
this.timeline_for_ui[index][0] = x2;
|
||||
}
|
||||
for (let index = 0; index < this.timeline_for_ui.length; index++) {
|
||||
if (index == this.timeline_for_ui.length - 1) {
|
||||
return;
|
||||
draw() {
|
||||
this.signal_blocks_container.removeChildren();
|
||||
this.timeline.blocks.forEach((timeline_block) => {
|
||||
const signal_block = new Container();
|
||||
signal_block.x = timeline_block.x;
|
||||
this.signal_blocks_container.addChild(signal_block);
|
||||
const background = new Graphics().roundRect(0, 0, timeline_block.width, this.row_height, 15).fill("SlateBlue");
|
||||
signal_block.addChild(background);
|
||||
if (timeline_block.label !== void 0) {
|
||||
const label = new Text({ text: timeline_block.label.text, style: this.label_style });
|
||||
label.x = timeline_block.label.x;
|
||||
label.y = timeline_block.label.y;
|
||||
signal_block.addChild(label);
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
const [x2, value] = this.timeline_for_ui[index];
|
||||
const block_width = this.timeline_for_ui[index + 1][0] - x2;
|
||||
const block_height = this.row_height;
|
||||
const block_visible = block_width >= MIN_BLOCK_WIDTH;
|
||||
let signal_block = this.signal_blocks_container.children[index];
|
||||
if (signal_block === void 0 && !block_visible) {
|
||||
return;
|
||||
}
|
||||
if (signal_block !== void 0 && !block_visible) {
|
||||
signal_block.visible = false;
|
||||
return;
|
||||
}
|
||||
if (signal_block === void 0 && block_visible) {
|
||||
signal_block = new Container();
|
||||
signal_block.x = x2;
|
||||
this.signal_blocks_container.addChild(signal_block);
|
||||
} else if (signal_block !== void 0 && block_visible) {
|
||||
signal_block.visible = true;
|
||||
signal_block.x = x2;
|
||||
}
|
||||
let background = signal_block.getChildByLabel("background");
|
||||
if (background === null) {
|
||||
background = new Graphics().roundRect(0, 0, block_width, block_height, 15).fill("SlateBlue");
|
||||
background.label = "background";
|
||||
signal_block.addChild(background);
|
||||
} else {
|
||||
background.width = block_width;
|
||||
}
|
||||
const label = signal_block.getChildByLabel("label");
|
||||
if (label === null) {
|
||||
const label2 = new Text({ text: value, style: this.label_style });
|
||||
label2.x = (block_width - label2.width) / 2;
|
||||
label2.y = (block_height - label2.height) / 2;
|
||||
label2.visible = label2.width < block_width;
|
||||
label2.label = "label";
|
||||
signal_block.addChild(label2);
|
||||
} else {
|
||||
label.x = (block_width - label.width) / 2;
|
||||
label.y = (block_height - label.height) / 2;
|
||||
label.visible = label.width < block_width;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
decrement_index() {
|
||||
this.index_in_owner--;
|
||||
|
|
|
@ -2526,6 +2526,9 @@ async function get_time_table() {
|
|||
async function load_and_get_signal(signal_ref_index) {
|
||||
return await invoke2("load_and_get_signal", { signal_ref_index });
|
||||
}
|
||||
async function timeline(signal_ref_index, screen_width) {
|
||||
return await invoke2("timeline", { signal_ref_index, screen_width });
|
||||
}
|
||||
async function unload_signal(signal_ref_index) {
|
||||
return await invoke2("unload_signal", { signal_ref_index });
|
||||
}
|
||||
|
@ -2535,5 +2538,6 @@ export {
|
|||
load_and_get_signal,
|
||||
pick_and_load_waveform,
|
||||
show_window,
|
||||
timeline,
|
||||
unload_signal
|
||||
};
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
import { Application, Text, Graphics, Container, TextStyle, ContainerChild } from "pixi.js";
|
||||
|
||||
type Time = number;
|
||||
type BitString = string;
|
||||
type Timeline = Array<[Time, BitString]>;
|
||||
|
||||
type X = number;
|
||||
type TimelineForUI = Array<[X, string]>;
|
||||
|
||||
const MIN_BLOCK_WIDTH = 1;
|
||||
// @TODO sync with Rust and `tauri_glue.ts`
|
||||
type Timeline = {
|
||||
blocks: Array<TimelineBlock>
|
||||
}
|
||||
type TimelineBlock = {
|
||||
x: number,
|
||||
width: number,
|
||||
label: TimeLineBlockLabel | undefined,
|
||||
}
|
||||
type TimeLineBlockLabel = {
|
||||
text: string,
|
||||
x: number,
|
||||
y: number,
|
||||
}
|
||||
|
||||
export class PixiController {
|
||||
app: Application
|
||||
|
@ -48,6 +54,10 @@ export class PixiController {
|
|||
this.app.destroy(rendererDestroyOptions, options);
|
||||
}
|
||||
|
||||
screen_width() {
|
||||
return this.app.screen.width;
|
||||
}
|
||||
|
||||
// -- FastWave-specific --
|
||||
|
||||
remove_var(index: number) {
|
||||
|
@ -57,6 +67,7 @@ export class PixiController {
|
|||
}
|
||||
|
||||
push_var(timeline: Timeline) {
|
||||
console.log("Timline in Typescript:", timeline);
|
||||
new VarSignalRow(
|
||||
timeline,
|
||||
this.app,
|
||||
|
@ -79,17 +90,13 @@ export class PixiController {
|
|||
class VarSignalRow {
|
||||
app: Application;
|
||||
timeline: Timeline;
|
||||
last_time: Time;
|
||||
formatter: (signal_value: BitString) => string;
|
||||
timeline_for_ui: TimelineForUI;
|
||||
owner: Array<VarSignalRow>;
|
||||
index_in_owner: number;
|
||||
rows_container: Container;
|
||||
row_height: number;
|
||||
row_gap: number;
|
||||
row_height_with_gap: number;
|
||||
renderer_resize_callback = () => this.redraw_on_canvas_resize();
|
||||
// -- elements --
|
||||
renderer_resize_callback = () => this.draw();
|
||||
row_container = new Container();
|
||||
signal_blocks_container = new Container();
|
||||
label_style = new TextStyle({
|
||||
|
@ -110,13 +117,6 @@ class VarSignalRow {
|
|||
this.app = app;
|
||||
|
||||
this.timeline = timeline;
|
||||
this.last_time = timeline[timeline.length - 1][0];
|
||||
this.formatter = signal_value => parseInt(signal_value, 2).toString(16);
|
||||
|
||||
this.timeline_for_ui = this.timeline.map(([time, value]) => {
|
||||
const x = time / this.last_time * this.app.screen.width;
|
||||
return [x, this.formatter(value)]
|
||||
});
|
||||
|
||||
this.row_height = row_height;
|
||||
this.row_gap = row_gap;
|
||||
|
@ -128,113 +128,43 @@ class VarSignalRow {
|
|||
|
||||
this.rows_container = rows_container;
|
||||
|
||||
this.draw();
|
||||
this.app.renderer.on("resize", this.renderer_resize_callback);
|
||||
}
|
||||
|
||||
async draw() {
|
||||
// row_container
|
||||
this.row_container.y = this.index_in_owner * this.row_height_with_gap;
|
||||
this.rows_container.addChild(this.row_container);
|
||||
|
||||
// signal_block_container
|
||||
// signal_blocks_container
|
||||
this.row_container.addChild(this.signal_blocks_container);
|
||||
|
||||
for (let index = 0; index < this.timeline_for_ui.length; index++) {
|
||||
if (index == this.timeline_for_ui.length - 1) {
|
||||
return;
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
const [x, value] = this.timeline_for_ui[index];
|
||||
this.draw();
|
||||
// this.app.renderer.on("resize", (width, height) => {
|
||||
// // @TODO only on `width` change
|
||||
// // @TODO inline `renderer_resize_callback`?
|
||||
// this.draw();
|
||||
// });
|
||||
}
|
||||
|
||||
draw() {
|
||||
this.signal_blocks_container.removeChildren();
|
||||
this.timeline.blocks.forEach(timeline_block => {
|
||||
// signal_block
|
||||
const block_width = this.timeline_for_ui[index+1][0] - x;
|
||||
const block_height = this.row_height;
|
||||
if (block_width < MIN_BLOCK_WIDTH) {
|
||||
return;
|
||||
}
|
||||
const signal_block = new Container();
|
||||
signal_block.x = x;
|
||||
signal_block.x = timeline_block.x;
|
||||
this.signal_blocks_container.addChild(signal_block);
|
||||
|
||||
// background
|
||||
const background = new Graphics()
|
||||
.roundRect(0, 0, block_width, block_height, 15)
|
||||
.roundRect(0, 0, timeline_block.width, this.row_height, 15)
|
||||
.fill("SlateBlue");
|
||||
background.label = "background";
|
||||
signal_block.addChild(background);
|
||||
|
||||
// label
|
||||
const label = new Text({ text: value, style: this.label_style });
|
||||
label.x = (block_width - label.width) / 2;
|
||||
label.y = (block_height - label.height) / 2;
|
||||
label.visible = label.width < block_width;
|
||||
label.label = "label";
|
||||
signal_block.addChild(label);
|
||||
}
|
||||
}
|
||||
|
||||
async redraw_on_canvas_resize() {
|
||||
for (let index = 0; index < this.timeline_for_ui.length; index++) {
|
||||
const x = this.timeline[index][0] / this.last_time * this.app.screen.width;
|
||||
this.timeline_for_ui[index][0] = x;
|
||||
}
|
||||
for (let index = 0; index < this.timeline_for_ui.length; index++) {
|
||||
if (index == this.timeline_for_ui.length - 1) {
|
||||
return;
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
const [x, value] = this.timeline_for_ui[index];
|
||||
|
||||
// signal_block
|
||||
const block_width = this.timeline_for_ui[index+1][0] - x;
|
||||
const block_height = this.row_height;
|
||||
const block_visible = block_width >= MIN_BLOCK_WIDTH;
|
||||
|
||||
let signal_block: ContainerChild | undefined = this.signal_blocks_container.children[index];
|
||||
if (signal_block === undefined && !block_visible) {
|
||||
return;
|
||||
}
|
||||
if (signal_block !== undefined && !block_visible) {
|
||||
signal_block.visible = false;
|
||||
return;
|
||||
}
|
||||
if (signal_block === undefined && block_visible) {
|
||||
signal_block = new Container();
|
||||
signal_block.x = x;
|
||||
this.signal_blocks_container.addChild(signal_block);
|
||||
} else if (signal_block !== undefined && block_visible) {
|
||||
signal_block.visible = true;
|
||||
signal_block.x = x;
|
||||
}
|
||||
|
||||
// background
|
||||
let background = signal_block.getChildByLabel("background");
|
||||
if (background === null) {
|
||||
background = new Graphics()
|
||||
.roundRect(0, 0, block_width, block_height, 15)
|
||||
.fill("SlateBlue");
|
||||
background.label = "background";
|
||||
signal_block.addChild(background);
|
||||
} else {
|
||||
background.width = block_width;
|
||||
}
|
||||
|
||||
// label
|
||||
const label = signal_block.getChildByLabel("label");
|
||||
if (label === null ) {
|
||||
const label = new Text({ text: value, style: this.label_style });
|
||||
label.x = (block_width - label.width) / 2;
|
||||
label.y = (block_height - label.height) / 2;
|
||||
label.visible = label.width < block_width;
|
||||
label.label = "label";
|
||||
if (timeline_block.label !== undefined) {
|
||||
const label = new Text({ text: timeline_block.label.text, style: this.label_style });
|
||||
label.x = timeline_block.label.x;
|
||||
label.y = timeline_block.label.y;
|
||||
signal_block.addChild(label);
|
||||
} else {
|
||||
label.x = (block_width - label.width) / 2;
|
||||
label.y = (block_height - label.height) / 2;
|
||||
label.visible = label.width < block_width;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
decrement_index() {
|
||||
|
|
|
@ -8,6 +8,7 @@ type Filename = string;
|
|||
type WellenHierarchy = unknown;
|
||||
type WellenTimeTable = unknown;
|
||||
type WellenSignal = unknown;
|
||||
type Timeline = unknown;
|
||||
|
||||
export async function show_window(): Promise<void> {
|
||||
return await invoke("show_window");
|
||||
|
@ -29,6 +30,10 @@ export async function load_and_get_signal(signal_ref_index: number): Promise<Wel
|
|||
return await invoke("load_and_get_signal", { signal_ref_index });
|
||||
}
|
||||
|
||||
export async function timeline(signal_ref_index: number, screen_width: number): Promise<Timeline> {
|
||||
return await invoke("timeline", { signal_ref_index, screen_width });
|
||||
}
|
||||
|
||||
export async function unload_signal(signal_ref_index: number): Promise<void> {
|
||||
return await invoke("unload_signal", { signal_ref_index });
|
||||
}
|
||||
|
|
|
@ -9,3 +9,10 @@ publish.workspace = true
|
|||
|
||||
[dependencies]
|
||||
wellen.workspace = true
|
||||
moonlight.workspace = true
|
||||
# @TODO update `futures_util_ext` - add feature `sink`, set exact `futures-util` version
|
||||
futures-util = { version = "0.3.30", features = ["sink"] }
|
||||
|
||||
[features]
|
||||
frontend = ["moonlight/frontend"]
|
||||
backend = ["moonlight/backend"]
|
||||
|
|
|
@ -1 +1,25 @@
|
|||
use moonlight::*;
|
||||
|
||||
pub mod wellen_helpers;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(crate = "serde")]
|
||||
pub struct Timeline {
|
||||
pub blocks: Vec<TimelineBlock>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(crate = "serde")]
|
||||
pub struct TimelineBlock {
|
||||
pub x: u32,
|
||||
pub width: u32,
|
||||
pub label: Option<TimeLineBlockLabel>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(crate = "serde")]
|
||||
pub struct TimeLineBlockLabel {
|
||||
pub text: String,
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ crate-type = ["staticlib", "cdylib", "rlib"]
|
|||
tauri-build = { version = "=2.0.0-beta.17", features = [] }
|
||||
|
||||
[dependencies]
|
||||
shared.workspace = true
|
||||
wellen.workspace = true
|
||||
shared = { path = "../shared", features = ["backend"] }
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "=2.0.0-beta.22", features = ["macos-private-api", "linux-ipc-protocol"] }
|
||||
|
|
|
@ -61,6 +61,25 @@ async fn load_and_get_signal(
|
|||
Ok(serde_json::to_value(signal).unwrap())
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn timeline(
|
||||
signal_ref_index: usize,
|
||||
screen_width: u32,
|
||||
store: tauri::State<'_, Store>,
|
||||
) -> Result<serde_json::Value, ()> {
|
||||
let signal_ref = wellen::SignalRef::from_index(signal_ref_index).unwrap();
|
||||
let mut waveform_lock = store.waveform.lock().unwrap();
|
||||
let waveform = waveform_lock.as_mut().unwrap();
|
||||
// @TODO maybe run it in a thread to not block the main one or return the result through a Tauri channel
|
||||
waveform.load_signals_multi_threaded(&[signal_ref]);
|
||||
let signal = waveform.get_signal(signal_ref).unwrap();
|
||||
|
||||
// @TODO create Timeline
|
||||
let timeline = shared::Timeline { blocks: Vec::new() };
|
||||
|
||||
Ok(serde_json::to_value(timeline).unwrap())
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn unload_signal(signal_ref_index: usize, store: tauri::State<'_, Store>) -> Result<(), ()> {
|
||||
let signal_ref = wellen::SignalRef::from_index(signal_ref_index).unwrap();
|
||||
|
@ -87,6 +106,7 @@ pub fn run() {
|
|||
get_hierarchy,
|
||||
get_time_table,
|
||||
load_and_get_signal,
|
||||
timeline,
|
||||
unload_signal,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
|
|
Loading…
Reference in a new issue