use iced::{
widget::{button, column, container, row, text},
Element, Length, Subscription, Task,
};
use iced_webview::{Action, PageType, WebView};
#[cfg(not(feature = "servo"))]
use iced::time;
#[cfg(not(feature = "servo"))]
use std::time::Duration;
#[cfg(feature = "cef")]
type Engine = iced_webview::Cef;
#[cfg(all(feature = "servo", not(feature = "cef")))]
type Engine = iced_webview::Servo;
#[cfg(all(feature = "blitz", not(feature = "servo"), not(feature = "cef")))]
type Engine = iced_webview::Blitz;
#[cfg(all(
feature = "litehtml",
not(feature = "blitz"),
not(feature = "servo"),
not(feature = "cef")
))]
type Engine = iced_webview::Litehtml;
static URL: &str = "https://docs.rs/iced/latest/iced/index.html";
fn main() -> iced::Result {
#[cfg(feature = "cef")]
if iced_webview::cef_subprocess_check() {
return Ok(());
}
iced::application(App::new, App::update, App::view)
.title("An embedded web view")
.subscription(App::subscription)
.run()
}
#[derive(Debug, Clone)]
enum Message {
WebView(Action),
ToggleWebview,
UrlChanged(String),
WebviewCreated,
CreateWebview,
CycleWebview,
}
struct App {
webview: WebView<Engine, Message>,
show_webview: bool,
webview_url: Option<String>,
num_views: u32,
current_view: Option<u32>,
}
impl App {
fn new() -> (Self, Task<Message>) {
let webview = WebView::new()
.on_create_view(Message::WebviewCreated)
.on_url_change(Message::UrlChanged)
.on_action(Message::WebView);
(
Self {
webview,
show_webview: false,
webview_url: None,
num_views: 0,
current_view: None,
},
Task::done(Message::CreateWebview),
)
}
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::WebView(msg) => self.webview.update(msg),
Message::CreateWebview => self
.webview
.update(Action::CreateView(PageType::Url(URL.to_string()))),
Message::WebviewCreated => {
if self.current_view == None {
return Task::done(Message::CycleWebview);
}
self.num_views += 1;
Task::none()
}
Message::ToggleWebview => {
self.show_webview = !self.show_webview;
Task::none()
}
Message::UrlChanged(new_url) => {
self.webview_url = Some(new_url);
Task::none()
}
Message::CycleWebview => {
if let Some(current_view) = self.current_view.as_mut() {
if *current_view + 1 > self.num_views {
*current_view = 0;
} else {
*current_view += 1;
};
self.webview.update(Action::ChangeView(*current_view))
} else {
self.current_view = Some(0);
self.webview.update(Action::ChangeView(0))
}
}
}
}
fn view(&self) -> Element<Message> {
let mut column = column![row![
text(if !self.show_webview {
"Click the button to open a webview"
} else {
"Iced docs can be pulled up inside an iced app?! Whoa!"
}),
container(row![
button("Toggle web view(s)").on_press(Message::ToggleWebview),
button("New web view").on_press(Message::CreateWebview),
button("Switch views").on_press(Message::CycleWebview),
])
.align_right(Length::Fill)
]];
if self.show_webview {
if let Some(current_view) = self.current_view {
column = column.push(column![
text(format!("view index: {}", current_view)),
self.webview.view().map(Message::WebView),
text(format!("Url: {:?}", self.webview_url)),
]);
}
}
column.into()
}
fn subscription(&self) -> Subscription<Message> {
#[cfg(feature = "servo")]
{
self.webview.subscription().map(Message::WebView)
}
#[cfg(not(feature = "servo"))]
{
time::every(Duration::from_millis(10))
.map(|_| Action::Update)
.map(Message::WebView)
}
}
}