use std::io;
use rich_embed::PageState;
use serde_json::Value;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct TabId(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HistoryStep {
Back,
Forward,
Reload,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Rect {
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
}
impl Rect {
pub fn new(x: f64, y: f64, width: f64, height: f64) -> Rect {
Rect {
x,
y,
width,
height,
}
}
pub fn right(&self) -> f64 {
self.x + self.width
}
pub fn bottom(&self) -> f64 {
self.y + self.height
}
pub fn is_empty(&self) -> bool {
self.width <= 0.0 || self.height <= 0.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Format {
Png,
Jpeg,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Frame {
pub format: Format,
pub bytes: Vec<u8>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PageSnapshot {
pub dom: Value,
pub ax: Value,
}
pub type NodeId = i64;
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Playback {
pub paused: bool,
pub muted: bool,
pub volume: f64,
pub time: f64,
pub duration: Option<f64>,
pub ended: bool,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum MediaOp {
Play,
Pause,
Mute(bool),
Volume(f64),
}
#[derive(Clone, Debug, PartialEq)]
pub enum PageAction {
Click(NodeId),
Focus(NodeId),
InsertText(String),
SetValue { node: NodeId, value: String },
SelectOption { select: NodeId, option: NodeId },
SetRange { node: NodeId, value: f64 },
ScrollTo(f64),
Media { node: NodeId, op: MediaOp },
}
#[derive(Clone, Debug, PartialEq)]
pub enum EngineEvent {
Changed,
Navigated(String),
Loaded,
DownloadBegan {
guid: String,
name: String,
url: String,
},
DownloadDone { guid: String, path: String },
}
pub trait Engine: Send {
fn resize(&mut self, columns: u16, rows: u16) -> io::Result<()>;
fn open(&mut self, tab: TabId, url: &str) -> io::Result<()>;
fn new_tab(&mut self, _url: &str) -> io::Result<TabId> {
Err(io::Error::new(
io::ErrorKind::Unsupported,
"this engine has one tab",
))
}
fn close_tab(&mut self, _tab: TabId) -> io::Result<()> {
Err(io::Error::new(
io::ErrorKind::Unsupported,
"this engine has one tab",
))
}
fn history(&mut self, tab: TabId, step: HistoryStep) -> io::Result<()>;
fn state(&self, tab: TabId) -> PageState;
fn snapshot(&mut self, tab: TabId) -> io::Result<PageSnapshot>;
fn capture(&mut self, tab: TabId, region: Rect, format: Format) -> io::Result<Frame>;
fn act(&mut self, tab: TabId, action: &PageAction) -> io::Result<()>;
fn playback(&mut self, _tab: TabId, _node: NodeId) -> io::Result<Playback> {
Err(io::Error::new(io::ErrorKind::Unsupported, "no media here"))
}
fn events(&mut self) -> Vec<EngineEvent>;
}