timeline_getter
This commit is contained in:
parent
64cc46d4ac
commit
c2f49901f6
Before Width: | Height: | Size: 434 KiB After Width: | Height: | Size: 434 KiB |
|
@ -99,7 +99,6 @@ impl ControlsPanel {
|
||||||
Layout::Columns => Height::fill().max(MILLER_COLUMN_MAX_HEIGHT),
|
Layout::Columns => Height::fill().max(MILLER_COLUMN_MAX_HEIGHT),
|
||||||
},
|
},
|
||||||
)))
|
)))
|
||||||
.s(Scrollbars::both())
|
|
||||||
.s(Padding::all(20))
|
.s(Padding::all(20))
|
||||||
.s(Gap::new().y(40))
|
.s(Gap::new().y(40))
|
||||||
.s(Align::new().top())
|
.s(Align::new().top())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{platform, HierarchyAndTimeTable};
|
use crate::{platform, HierarchyAndTimeTable};
|
||||||
use wellen::GetItem;
|
use wellen::GetItem;
|
||||||
use zoon::{eprintln, *};
|
use zoon::*;
|
||||||
|
|
||||||
mod pixi_canvas;
|
mod pixi_canvas;
|
||||||
use pixi_canvas::{PixiCanvas, PixiController};
|
use pixi_canvas::{PixiCanvas, PixiController};
|
||||||
|
@ -109,10 +109,6 @@ impl WaveformPanel {
|
||||||
var_ref: wellen::VarRef,
|
var_ref: wellen::VarRef,
|
||||||
) {
|
) {
|
||||||
let (hierarchy, time_table) = hierarchy_and_time_table.get_cloned().unwrap();
|
let (hierarchy, time_table) = hierarchy_and_time_table.get_cloned().unwrap();
|
||||||
if time_table.is_empty() {
|
|
||||||
eprintln!("timetable is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let var = hierarchy.get(var_ref);
|
let var = hierarchy.get(var_ref);
|
||||||
let signal_ref = var.signal_ref();
|
let signal_ref = var.signal_ref();
|
||||||
|
@ -128,7 +124,9 @@ impl WaveformPanel {
|
||||||
zoon::println!("{timescale:?}");
|
zoon::println!("{timescale:?}");
|
||||||
|
|
||||||
// Note: Sync `timeline`'s type with the `Timeline` in `frontend/typescript/pixi_canvas/pixi_canvas.ts'
|
// 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());
|
let timeline = serde_wasm_bindgen::to_value(&timeline).unwrap_throw();
|
||||||
|
let signal_ref_index = signal_ref.index();
|
||||||
|
controller.push_var(signal_ref_index, timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selected_var_panel(
|
fn selected_var_panel(
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
pub use js_bridge::PixiController;
|
pub use js_bridge::PixiController;
|
||||||
use zoon::*;
|
use zoon::*;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::platform;
|
||||||
|
|
||||||
pub struct PixiCanvas {
|
pub struct PixiCanvas {
|
||||||
raw_el: RawHtmlEl<web_sys::HtmlElement>,
|
raw_el: RawHtmlEl<web_sys::HtmlElement>,
|
||||||
|
@ -45,6 +47,16 @@ impl PixiCanvas {
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
let task_with_controller = Mutable::new(None);
|
let task_with_controller = Mutable::new(None);
|
||||||
|
// -- FastWave-specific --
|
||||||
|
let timeline_getter = Rc::new(Closure::new(|signal_ref_index, screen_width, row_height| {
|
||||||
|
future_to_promise(async move {
|
||||||
|
let signal_ref = wellen::SignalRef::from_index(signal_ref_index).unwrap_throw();
|
||||||
|
let timeline = platform::load_signal_and_get_timeline(signal_ref, screen_width, row_height).await;
|
||||||
|
let timeline = serde_wasm_bindgen::to_value(&timeline).unwrap_throw();
|
||||||
|
Ok(timeline)
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
// -- // --
|
||||||
Self {
|
Self {
|
||||||
controller: controller.read_only(),
|
controller: controller.read_only(),
|
||||||
width: width.read_only(),
|
width: width.read_only(),
|
||||||
|
@ -56,14 +68,15 @@ impl PixiCanvas {
|
||||||
width.set_neq(new_width);
|
width.set_neq(new_width);
|
||||||
height.set_neq(new_height);
|
height.set_neq(new_height);
|
||||||
}))
|
}))
|
||||||
.after_insert(clone!((controller) move |element| {
|
.after_insert(clone!((controller, timeline_getter) move |element| {
|
||||||
Task::start(async move {
|
Task::start(async move {
|
||||||
let pixi_controller = js_bridge::PixiController::new(row_height, row_gap);
|
let pixi_controller = js_bridge::PixiController::new(row_height, row_gap, &timeline_getter);
|
||||||
pixi_controller.init(&element).await;
|
pixi_controller.init(&element).await;
|
||||||
controller.set(Some(pixi_controller));
|
controller.set(Some(pixi_controller));
|
||||||
});
|
});
|
||||||
}))
|
}))
|
||||||
.after_remove(move |_| {
|
.after_remove(move |_| {
|
||||||
|
drop(timeline_getter);
|
||||||
drop(resize_task);
|
drop(resize_task);
|
||||||
drop(task_with_controller);
|
drop(task_with_controller);
|
||||||
if let Some(controller) = controller.take() {
|
if let Some(controller) = controller.take() {
|
||||||
|
@ -87,6 +100,12 @@ impl PixiCanvas {
|
||||||
mod js_bridge {
|
mod js_bridge {
|
||||||
use zoon::*;
|
use zoon::*;
|
||||||
|
|
||||||
|
type TimelinePromise = js_sys::Promise;
|
||||||
|
type SignalRefIndex = usize;
|
||||||
|
type ScreenWidth = u32;
|
||||||
|
type RowHeight = u32;
|
||||||
|
type TimelineGetter = Closure<dyn FnMut(SignalRefIndex, ScreenWidth, RowHeight) -> TimelinePromise>;
|
||||||
|
|
||||||
// Note: Add all corresponding methods to `frontend/typescript/pixi_canvas/pixi_canvas.ts`
|
// Note: Add all corresponding methods to `frontend/typescript/pixi_canvas/pixi_canvas.ts`
|
||||||
#[wasm_bindgen(module = "/typescript/bundles/pixi_canvas.js")]
|
#[wasm_bindgen(module = "/typescript/bundles/pixi_canvas.js")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -95,7 +114,7 @@ mod js_bridge {
|
||||||
|
|
||||||
// @TODO `row_height` and `row_gap` is FastWave-specific
|
// @TODO `row_height` and `row_gap` is FastWave-specific
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(row_height: u32, row_gap: u32) -> PixiController;
|
pub fn new(row_height: u32, row_gap: u32, timeline_getter: &TimelineGetter) -> PixiController;
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub async fn init(this: &PixiController, parent_element: &JsValue);
|
pub async fn init(this: &PixiController, parent_element: &JsValue);
|
||||||
|
@ -115,7 +134,7 @@ mod js_bridge {
|
||||||
pub fn remove_var(this: &PixiController, index: usize);
|
pub fn remove_var(this: &PixiController, index: usize);
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn push_var(this: &PixiController, timeline: JsValue);
|
pub fn push_var(this: &PixiController, signal_ref_index: usize, timeline: JsValue);
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn pop_var(this: &PixiController);
|
pub fn pop_var(this: &PixiController);
|
||||||
|
|
|
@ -35136,12 +35136,14 @@ var PixiController = class {
|
||||||
row_height;
|
row_height;
|
||||||
row_gap;
|
row_gap;
|
||||||
previous_parent_width;
|
previous_parent_width;
|
||||||
constructor(row_height, row_gap) {
|
timeline_getter;
|
||||||
|
constructor(row_height, row_gap, timeline_getter) {
|
||||||
this.app = new Application();
|
this.app = new Application();
|
||||||
this.row_height = row_height;
|
this.row_height = row_height;
|
||||||
this.row_gap = row_gap;
|
this.row_gap = row_gap;
|
||||||
this.app.stage.addChild(this.var_signal_rows_container);
|
this.app.stage.addChild(this.var_signal_rows_container);
|
||||||
this.previous_parent_width = null;
|
this.previous_parent_width = null;
|
||||||
|
this.timeline_getter = timeline_getter;
|
||||||
}
|
}
|
||||||
async init(parent_element) {
|
async init(parent_element) {
|
||||||
await this.app.init({ background: "DarkSlateBlue", antialias: true, resizeTo: parent_element });
|
await this.app.init({ background: "DarkSlateBlue", antialias: true, resizeTo: parent_element });
|
||||||
|
@ -35174,15 +35176,19 @@ var PixiController = class {
|
||||||
}
|
}
|
||||||
// -- FastWave-specific --
|
// -- FastWave-specific --
|
||||||
redraw_rows() {
|
redraw_rows() {
|
||||||
this.var_signal_rows.forEach((row) => row.draw());
|
this.var_signal_rows.forEach(async (row) => {
|
||||||
|
const timeline = await this.timeline_getter(row.signal_ref_index, this.app.screen.width, this.row_height);
|
||||||
|
row.redraw(timeline);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
remove_var(index) {
|
remove_var(index) {
|
||||||
if (typeof this.var_signal_rows[index] !== "undefined") {
|
if (typeof this.var_signal_rows[index] !== "undefined") {
|
||||||
this.var_signal_rows[index].destroy();
|
this.var_signal_rows[index].destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push_var(timeline) {
|
push_var(signal_ref_index, timeline) {
|
||||||
new VarSignalRow(
|
new VarSignalRow(
|
||||||
|
signal_ref_index,
|
||||||
timeline,
|
timeline,
|
||||||
this.app,
|
this.app,
|
||||||
this.var_signal_rows,
|
this.var_signal_rows,
|
||||||
|
@ -35199,8 +35205,9 @@ var PixiController = class {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var VarSignalRow = class {
|
var VarSignalRow = class {
|
||||||
app;
|
signal_ref_index;
|
||||||
timeline;
|
timeline;
|
||||||
|
app;
|
||||||
owner;
|
owner;
|
||||||
index_in_owner;
|
index_in_owner;
|
||||||
rows_container;
|
rows_container;
|
||||||
|
@ -35216,9 +35223,10 @@ var VarSignalRow = class {
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"'
|
fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"'
|
||||||
});
|
});
|
||||||
constructor(timeline, app, owner, rows_container, row_height, row_gap) {
|
constructor(signal_ref_index, timeline, app, owner, rows_container, row_height, row_gap) {
|
||||||
this.app = app;
|
this.signal_ref_index = signal_ref_index;
|
||||||
this.timeline = timeline;
|
this.timeline = timeline;
|
||||||
|
this.app = app;
|
||||||
this.row_height = row_height;
|
this.row_height = row_height;
|
||||||
this.row_gap = row_gap;
|
this.row_gap = row_gap;
|
||||||
this.row_height_with_gap = row_height + row_gap;
|
this.row_height_with_gap = row_height + row_gap;
|
||||||
|
@ -35241,6 +35249,9 @@ var VarSignalRow = class {
|
||||||
this.draw();
|
this.draw();
|
||||||
}
|
}
|
||||||
draw() {
|
draw() {
|
||||||
|
if (this.app.screen === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.row_container_background.width = this.app.screen.width;
|
this.row_container_background.width = this.app.screen.width;
|
||||||
this.signal_blocks_container.removeChildren();
|
this.signal_blocks_container.removeChildren();
|
||||||
this.timeline.blocks.forEach((timeline_block) => {
|
this.timeline.blocks.forEach((timeline_block) => {
|
||||||
|
|
|
@ -16,6 +16,8 @@ type TimeLineBlockLabel = {
|
||||||
y: number,
|
y: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TimelineGetter = (signal_ref_index: number, screen_width: number, row_height: number) => Promise<Timeline>;
|
||||||
|
|
||||||
export class PixiController {
|
export class PixiController {
|
||||||
app: Application
|
app: Application
|
||||||
// -- FastWave-specific --
|
// -- FastWave-specific --
|
||||||
|
@ -24,14 +26,16 @@ export class PixiController {
|
||||||
row_height: number;
|
row_height: number;
|
||||||
row_gap: number;
|
row_gap: number;
|
||||||
previous_parent_width: number | null;
|
previous_parent_width: number | null;
|
||||||
|
timeline_getter: TimelineGetter
|
||||||
|
|
||||||
constructor(row_height: number, row_gap: number) {
|
constructor(row_height: number, row_gap: number, timeline_getter: TimelineGetter) {
|
||||||
this.app = new Application();
|
this.app = new Application();
|
||||||
// -- FastWave-specific --
|
// -- FastWave-specific --
|
||||||
this.row_height = row_height;
|
this.row_height = row_height;
|
||||||
this.row_gap = row_gap;
|
this.row_gap = row_gap;
|
||||||
this.app.stage.addChild(this.var_signal_rows_container);
|
this.app.stage.addChild(this.var_signal_rows_container);
|
||||||
this.previous_parent_width = null;
|
this.previous_parent_width = null;
|
||||||
|
this.timeline_getter = timeline_getter;
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(parent_element: HTMLElement) {
|
async init(parent_element: HTMLElement) {
|
||||||
|
@ -71,7 +75,10 @@ export class PixiController {
|
||||||
// -- FastWave-specific --
|
// -- FastWave-specific --
|
||||||
|
|
||||||
redraw_rows() {
|
redraw_rows() {
|
||||||
this.var_signal_rows.forEach(row => row.draw());
|
this.var_signal_rows.forEach(async row => {
|
||||||
|
const timeline = await this.timeline_getter(row.signal_ref_index, this.app.screen.width, this.row_height);
|
||||||
|
row.redraw(timeline);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_var(index: number) {
|
remove_var(index: number) {
|
||||||
|
@ -80,8 +87,9 @@ export class PixiController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
push_var(timeline: Timeline) {
|
push_var(signal_ref_index: number, timeline: Timeline) {
|
||||||
new VarSignalRow(
|
new VarSignalRow(
|
||||||
|
signal_ref_index,
|
||||||
timeline,
|
timeline,
|
||||||
this.app,
|
this.app,
|
||||||
this.var_signal_rows,
|
this.var_signal_rows,
|
||||||
|
@ -101,8 +109,9 @@ export class PixiController {
|
||||||
}
|
}
|
||||||
|
|
||||||
class VarSignalRow {
|
class VarSignalRow {
|
||||||
app: Application;
|
signal_ref_index: number;
|
||||||
timeline: Timeline;
|
timeline: Timeline;
|
||||||
|
app: Application;
|
||||||
owner: Array<VarSignalRow>;
|
owner: Array<VarSignalRow>;
|
||||||
index_in_owner: number;
|
index_in_owner: number;
|
||||||
rows_container: Container;
|
rows_container: Container;
|
||||||
|
@ -120,6 +129,7 @@ class VarSignalRow {
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
signal_ref_index: number,
|
||||||
timeline: Timeline,
|
timeline: Timeline,
|
||||||
app: Application,
|
app: Application,
|
||||||
owner: Array<VarSignalRow>,
|
owner: Array<VarSignalRow>,
|
||||||
|
@ -127,9 +137,9 @@ class VarSignalRow {
|
||||||
row_height: number,
|
row_height: number,
|
||||||
row_gap: number,
|
row_gap: number,
|
||||||
) {
|
) {
|
||||||
this.app = app;
|
this.signal_ref_index = signal_ref_index;
|
||||||
|
|
||||||
this.timeline = timeline;
|
this.timeline = timeline;
|
||||||
|
this.app = app;
|
||||||
|
|
||||||
this.row_height = row_height;
|
this.row_height = row_height;
|
||||||
this.row_gap = row_gap;
|
this.row_gap = row_gap;
|
||||||
|
@ -164,6 +174,12 @@ class VarSignalRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
|
// Screen can be null when we are, for instance, switching between miller column and tree layout
|
||||||
|
// and then the canvas has to be recreated
|
||||||
|
if (this.app.screen === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.row_container_background.width = this.app.screen.width;
|
this.row_container_background.width = this.app.screen.width;
|
||||||
|
|
||||||
this.signal_blocks_container.removeChildren();
|
this.signal_blocks_container.removeChildren();
|
||||||
|
|
Loading…
Reference in a new issue