137 lines
4.0 KiB
Rust
137 lines
4.0 KiB
Rust
use iced::advanced::{mouse, text, Layout, Shell, Widget};
|
|||
|
|
use iced::{Element, Event, Length, Rectangle, Size};
|
||
|
|
use iced::advanced::layout::{Limits, Node};
|
||
|
|
use iced::advanced::renderer::Style;
|
||
|
|
use iced::advanced::widget::{Operation, Tree};
|
||
|
|
use iced::mouse::Cursor;
|
||
|
|
use iced::widget::text_input::Catalog;
|
||
|
|
|
||
|
|
pub struct NavigationArea<'a, Message, Theme, Renderer>
|
||
|
|
where
|
||
|
|
Theme: Catalog,
|
||
|
|
Renderer: text::Renderer,
|
||
|
|
{
|
||
|
|
content: Element<'a, Message, Theme, Renderer>,
|
||
|
|
on_back_click: Option<Message>,
|
||
|
|
on_forward_click: Option<Message>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl<'a, Message, Theme, Renderer> NavigationArea<'a, Message, Theme, Renderer>
|
||
|
|
where
|
||
|
|
Message: Clone,
|
||
|
|
Theme: Catalog,
|
||
|
|
Renderer: text::Renderer,
|
||
|
|
{
|
||
|
|
#[must_use]
|
||
|
|
pub fn new(content: impl Into<Element<'a, Message, Theme, Renderer>>) -> Self {
|
||
|
|
Self {
|
||
|
|
content: content.into(),
|
||
|
|
on_back_click: None,
|
||
|
|
on_forward_click: None,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[must_use]
|
||
|
|
pub fn on_back_click(mut self, message: Message) -> Self {
|
||
|
|
self.on_back_click = Some(message);
|
||
|
|
self
|
||
|
|
}
|
||
|
|
|
||
|
|
#[must_use]
|
||
|
|
pub fn on_forward_click(mut self, message: Message) -> Self {
|
||
|
|
self.on_forward_click = Some(message);
|
||
|
|
self
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl<'a, Message, Theme, Renderer> From<NavigationArea<'a, Message, Theme, Renderer>>
|
||
|
|
for Element<'a, Message, Theme, Renderer>
|
||
|
|
where
|
||
|
|
Message: Clone + 'a,
|
||
|
|
Theme: Catalog + 'a,
|
||
|
|
Renderer: text::Renderer + 'a,
|
||
|
|
{
|
||
|
|
fn from(value: NavigationArea<'a, Message, Theme, Renderer>) -> Self {
|
||
|
|
Element::new(value)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn navigation_area<'a, Message, Theme, Renderer>(content: impl Into<Element<'a, Message, Theme, Renderer>>) -> NavigationArea<'a, Message, Theme, Renderer>
|
||
|
|
where
|
||
|
|
Message: Clone,
|
||
|
|
Theme: Catalog,
|
||
|
|
Renderer: text::Renderer,
|
||
|
|
{
|
||
|
|
NavigationArea::new(content)
|
||
|
|
}
|
||
|
|
|
||
|
|
impl <Message, Theme, Renderer> Widget<Message, Theme, Renderer> for NavigationArea<'_, Message, Theme, Renderer>
|
||
|
|
where
|
||
|
|
Message: Clone,
|
||
|
|
Theme: Catalog,
|
||
|
|
Renderer: text::Renderer,
|
||
|
|
{
|
||
|
|
fn size(&self) -> Size<Length> {
|
||
|
|
self.content.as_widget().size()
|
||
|
|
}
|
||
|
|
|
||
|
|
fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &Limits) -> Node {
|
||
|
|
self.content
|
||
|
|
.as_widget_mut()
|
||
|
|
.layout(&mut tree.children[0], renderer, limits)
|
||
|
|
}
|
||
|
|
|
||
|
|
fn draw(&self, tree: &Tree, renderer: &mut Renderer, theme: &Theme, style: &Style, layout: Layout<'_>, cursor: Cursor, viewport: &Rectangle) {
|
||
|
|
self.content.as_widget().draw(
|
||
|
|
&tree.children[0],
|
||
|
|
renderer,
|
||
|
|
theme,
|
||
|
|
style,
|
||
|
|
layout,
|
||
|
|
cursor,
|
||
|
|
viewport,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
fn diff(&mut self, tree: &mut Tree) {
|
||
|
|
tree.diff_children(std::slice::from_mut(&mut self.content));
|
||
|
|
}
|
||
|
|
|
||
|
|
fn operate(&mut self, tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, operation: &mut dyn Operation) {
|
||
|
|
self.content
|
||
|
|
.as_widget_mut()
|
||
|
|
.operate(&mut tree.children[0], layout, renderer, operation);
|
||
|
|
}
|
||
|
|
|
||
|
|
fn update(&mut self, tree: &mut Tree, event: &Event, layout: Layout<'_>, cursor: Cursor, renderer: &Renderer, shell: &mut Shell<'_, Message>, viewport: &Rectangle) {
|
||
|
|
self.content.as_widget_mut().update(
|
||
|
|
&mut tree.children[0],
|
||
|
|
event,
|
||
|
|
layout,
|
||
|
|
cursor,
|
||
|
|
renderer,
|
||
|
|
shell,
|
||
|
|
viewport,
|
||
|
|
);
|
||
|
|
|
||
|
|
if shell.is_event_captured() {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
match event {
|
||
|
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Back)) => {
|
||
|
|
if let Some(on_back_click) = &self.on_back_click {
|
||
|
|
shell.publish(on_back_click.clone());
|
||
|
|
shell.capture_event();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Forward)) => {
|
||
|
|
if let Some(on_forward_click) = &self.on_forward_click {
|
||
|
|
shell.publish(on_forward_click.clone());
|
||
|
|
shell.capture_event();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
_ => {}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|