Files
tools/publish/src/widget/navigation_area.rs
T
2026-07-22 21:41:57 -04:00

171 lines
4.9 KiB
Rust

use iced::advanced::{mouse, text, Layout, Shell, Widget, overlay};
use iced::{Element, Event, Length, Rectangle, Size, Vector};
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();
}
}
_ => {}
}
}
fn mouse_interaction(
&self,
tree: &Tree,
layout: Layout<'_>,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.content.as_widget().mouse_interaction(
&tree.children[0],
layout,
cursor,
viewport,
renderer,
)
}
fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'b>,
renderer: &Renderer,
viewport: &Rectangle,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.content.as_widget_mut().overlay(
&mut tree.children[0],
layout,
renderer,
viewport,
translation,
)
}
}