use crate::{
MainWindow, RemoteWorkerModel, SettingsModel, TiltVideoExportModel, WorkerItem,
settings::{ExportTransfer, PreviewScale, RemoteEndpoint, WorkerSettings},
};
use indicatrix_net::messages::TransferMode;
use slint::ComponentHandle;
const fn transfer_mode_index(mode: TransferMode) -> i32 {
match mode {
TransferMode::LiveProgressive | TransferMode::DisplayOnly => 0,
TransferMode::FinalOnly => 1,
}
}
const fn transfer_mode_from_index(idx: i32) -> TransferMode {
if idx == 1 {
TransferMode::FinalOnly
} else {
TransferMode::LiveProgressive
}
}
const fn preview_scale_parts(scale: PreviewScale) -> (i32, i32) {
match scale {
PreviewScale::Full => (0, 50),
PreviewScale::Half => (1, 50),
PreviewScale::Quarter => (2, 50),
PreviewScale::Custom(pct) => (3, pct as i32),
}
}
fn preview_scale_from_parts(idx: i32, pct: i32) -> PreviewScale {
match idx {
1 => PreviewScale::Half,
2 => PreviewScale::Quarter,
3 => PreviewScale::Custom(pct.clamp(1, 100) as u32),
_ => PreviewScale::Full,
}
}
fn to_worker_item(endpoint: &RemoteEndpoint) -> WorkerItem {
let w = &endpoint.connection;
let (preview_scale_index, preview_scale_percent) = preview_scale_parts(w.preview_scale);
WorkerItem {
name: w.name.clone().into(),
address: w.address.clone().into(),
cert_dir: w.cert_dir.clone().into(),
transfer_mode_index: transfer_mode_index(w.transfer_mode),
cadence_ms: w.cadence_ms as i32,
preview_scale_index,
preview_scale_percent,
export_transfer_index: endpoint.export_transfer.index(),
}
}
pub(super) fn from_worker_item(
item: &WorkerItem,
previous: Option<&RemoteEndpoint>,
) -> RemoteEndpoint {
RemoteEndpoint {
connection: WorkerSettings {
name: item.name.to_string(),
address: item.address.to_string(),
cert_dir: item.cert_dir.to_string(),
transfer_mode: transfer_mode_from_index(item.transfer_mode_index),
cadence_ms: item.cadence_ms.max(1) as u32,
preview_scale: preview_scale_from_parts(
item.preview_scale_index,
item.preview_scale_percent,
),
},
export_transfer: ExportTransfer::from_index(item.export_transfer_index),
live_transfer: previous.map(|p| p.live_transfer).unwrap_or_default(),
}
}
pub fn refresh_remote_ui(ui: &MainWindow, remote: Option<&RemoteEndpoint>) {
let model = ui.global::<RemoteWorkerModel>();
model.set_configured(remote.is_some());
model.set_endpoint(to_worker_item(&remote.cloned().unwrap_or_default()));
ui.global::<SettingsModel>()
.set_live_transfer_index(remote.map_or(0, |r| r.live_transfer.index()));
let video = ui.global::<TiltVideoExportModel>();
video.set_remote_configured(remote.is_some());
video.set_transfer_index(remote.map_or(0, |r| r.export_transfer.index()));
}
#[cfg(test)]
mod tests {
use super::*;
use crate::settings::LiveTransfer;
#[test]
fn a_form_round_trip_keeps_every_field_and_the_live_transfer() {
let endpoint = RemoteEndpoint {
connection: WorkerSettings {
name: "Coordinator".to_string(),
address: "coord.lan:7878".to_string(),
cert_dir: "C:/certs/coord".to_string(),
transfer_mode: TransferMode::FinalOnly,
cadence_ms: 750,
preview_scale: PreviewScale::Custom(40),
},
export_transfer: ExportTransfer::FinalPicture,
live_transfer: LiveTransfer::FinalPicture,
};
let item = to_worker_item(&endpoint);
assert_eq!(item.export_transfer_index, 1);
assert_eq!(from_worker_item(&item, Some(&endpoint)), endpoint);
assert_eq!(
from_worker_item(&item, None).live_transfer,
LiveTransfer::FullData
);
}
}