2023-09-07 02:45:15 +02:00
|
|
|
use iced::event::{self, Event};
|
2023-07-27 01:02:47 +02:00
|
|
|
use iced::mouse;
|
2023-07-27 01:21:50 +02:00
|
|
|
use iced::widget::{
|
2025-09-17 23:49:01 +02:00
|
|
|
self, column, container, row, scrollable, selector, space, text,
|
2023-07-27 01:21:50 +02:00
|
|
|
};
|
2023-07-27 01:29:20 +02:00
|
|
|
use iced::window;
|
2023-07-27 01:02:47 +02:00
|
|
|
use iced::{
|
2024-07-12 18:12:34 +02:00
|
|
|
Center, Color, Element, Fill, Font, Point, Rectangle, Subscription, Task,
|
|
|
|
|
Theme,
|
2023-07-27 01:02:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub fn main() -> iced::Result {
|
2025-03-12 02:10:42 +01:00
|
|
|
iced::application(Example::default, Example::update, Example::view)
|
2024-03-17 18:37:29 +01:00
|
|
|
.subscription(Example::subscription)
|
2025-09-08 05:16:20 +02:00
|
|
|
.theme(Theme::Dark)
|
2024-03-17 18:37:29 +01:00
|
|
|
.run()
|
2023-07-27 01:02:47 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:29 +01:00
|
|
|
#[derive(Default)]
|
2023-07-27 01:02:47 +02:00
|
|
|
struct Example {
|
|
|
|
|
mouse_position: Option<Point>,
|
|
|
|
|
outer_bounds: Option<Rectangle>,
|
|
|
|
|
inner_bounds: Option<Rectangle>,
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-23 05:15:57 +02:00
|
|
|
#[derive(Debug, Clone)]
|
2023-07-27 01:02:47 +02:00
|
|
|
enum Message {
|
|
|
|
|
MouseMoved(Point),
|
2023-07-27 01:29:20 +02:00
|
|
|
WindowResized,
|
2024-02-05 00:51:51 +01:00
|
|
|
Scrolled,
|
2024-11-05 14:06:36 +01:00
|
|
|
OuterFound(Option<selector::Target>),
|
|
|
|
|
InnerFound(Option<selector::Target>),
|
2023-07-27 01:02:47 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:29 +01:00
|
|
|
impl Example {
|
2024-06-14 01:47:39 +02:00
|
|
|
fn update(&mut self, message: Message) -> Task<Message> {
|
2023-07-27 01:02:47 +02:00
|
|
|
match message {
|
|
|
|
|
Message::MouseMoved(position) => {
|
|
|
|
|
self.mouse_position = Some(position);
|
|
|
|
|
|
2024-06-14 01:47:39 +02:00
|
|
|
Task::none()
|
2023-07-27 01:02:47 +02:00
|
|
|
}
|
2024-06-14 01:47:39 +02:00
|
|
|
Message::Scrolled | Message::WindowResized => Task::batch(vec![
|
2024-11-05 14:06:36 +01:00
|
|
|
selector::find(OUTER_CONTAINER).map(Message::OuterFound),
|
|
|
|
|
selector::find(INNER_CONTAINER).map(Message::InnerFound),
|
2024-02-05 00:51:51 +01:00
|
|
|
]),
|
2025-08-23 05:15:57 +02:00
|
|
|
Message::OuterFound(outer) => {
|
2024-11-05 14:06:36 +01:00
|
|
|
self.outer_bounds =
|
|
|
|
|
outer.as_ref().and_then(selector::Target::visible_bounds);
|
2023-07-27 01:02:47 +02:00
|
|
|
|
2024-06-14 01:47:39 +02:00
|
|
|
Task::none()
|
2023-07-27 01:02:47 +02:00
|
|
|
}
|
2025-08-23 05:15:57 +02:00
|
|
|
Message::InnerFound(inner) => {
|
2024-11-05 14:06:36 +01:00
|
|
|
self.inner_bounds =
|
|
|
|
|
inner.as_ref().and_then(selector::Target::visible_bounds);
|
2023-07-27 01:02:47 +02:00
|
|
|
|
2024-06-14 01:47:39 +02:00
|
|
|
Task::none()
|
2023-07-27 01:02:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-24 14:29:36 +02:00
|
|
|
fn view(&self) -> Element<'_, Message> {
|
2023-07-27 01:21:50 +02:00
|
|
|
let data_row = |label, value, color| {
|
|
|
|
|
row![
|
|
|
|
|
text(label),
|
2025-09-17 23:49:01 +02:00
|
|
|
space::horizontal(),
|
2024-03-04 19:31:26 +01:00
|
|
|
text(value)
|
|
|
|
|
.font(Font::MONOSPACE)
|
|
|
|
|
.size(14)
|
|
|
|
|
.color_maybe(color),
|
2023-07-27 01:21:50 +02:00
|
|
|
]
|
|
|
|
|
.height(40)
|
2024-07-12 18:12:34 +02:00
|
|
|
.align_y(Center)
|
2023-07-27 01:21:50 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let view_bounds = |label, bounds: Option<Rectangle>| {
|
|
|
|
|
data_row(
|
|
|
|
|
label,
|
2023-07-27 01:02:47 +02:00
|
|
|
match bounds {
|
2023-09-19 01:31:10 -04:00
|
|
|
Some(bounds) => format!("{bounds:?}"),
|
2023-07-27 01:02:47 +02:00
|
|
|
None => "not visible".to_string(),
|
2023-07-27 01:21:50 +02:00
|
|
|
},
|
|
|
|
|
if bounds
|
|
|
|
|
.zip(self.mouse_position)
|
|
|
|
|
.map(|(bounds, mouse_position)| {
|
|
|
|
|
bounds.contains(mouse_position)
|
|
|
|
|
})
|
|
|
|
|
.unwrap_or_default()
|
|
|
|
|
{
|
2024-03-04 19:31:26 +01:00
|
|
|
Some(Color {
|
2023-07-27 01:21:50 +02:00
|
|
|
g: 1.0,
|
|
|
|
|
..Color::BLACK
|
2024-03-04 19:31:26 +01:00
|
|
|
})
|
2023-07-27 01:21:50 +02:00
|
|
|
} else {
|
2024-03-04 19:31:26 +01:00
|
|
|
None
|
2023-07-27 01:21:50 +02:00
|
|
|
},
|
|
|
|
|
)
|
2023-07-27 01:02:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
column![
|
2023-07-27 01:21:50 +02:00
|
|
|
data_row(
|
|
|
|
|
"Mouse position",
|
2023-07-27 01:02:47 +02:00
|
|
|
match self.mouse_position {
|
|
|
|
|
Some(Point { x, y }) => format!("({x}, {y})"),
|
|
|
|
|
None => "unknown".to_string(),
|
2023-07-27 01:21:50 +02:00
|
|
|
},
|
2024-03-04 19:31:26 +01:00
|
|
|
None,
|
2023-07-27 01:21:50 +02:00
|
|
|
),
|
|
|
|
|
view_bounds("Outer container", self.outer_bounds),
|
|
|
|
|
view_bounds("Inner container", self.inner_bounds),
|
2023-07-27 01:02:47 +02:00
|
|
|
scrollable(
|
|
|
|
|
column![
|
|
|
|
|
text("Scroll me!"),
|
2025-09-17 23:49:01 +02:00
|
|
|
space().height(400),
|
2023-07-27 01:02:47 +02:00
|
|
|
container(text("I am the outer container!"))
|
2025-08-23 02:04:30 +02:00
|
|
|
.id(OUTER_CONTAINER)
|
2023-07-27 01:02:47 +02:00
|
|
|
.padding(40)
|
2024-03-08 18:57:44 +01:00
|
|
|
.style(container::rounded_box),
|
2025-09-17 23:49:01 +02:00
|
|
|
space().height(400),
|
2023-07-27 01:02:47 +02:00
|
|
|
scrollable(
|
|
|
|
|
column![
|
|
|
|
|
text("Scroll me!"),
|
2025-09-17 23:49:01 +02:00
|
|
|
space().height(400),
|
2023-07-27 01:02:47 +02:00
|
|
|
container(text("I am the inner container!"))
|
2025-08-23 02:04:30 +02:00
|
|
|
.id(INNER_CONTAINER)
|
2023-07-27 01:02:47 +02:00
|
|
|
.padding(40)
|
2024-03-08 18:57:44 +01:00
|
|
|
.style(container::rounded_box),
|
2025-09-17 23:49:01 +02:00
|
|
|
space().height(400),
|
2023-07-27 01:02:47 +02:00
|
|
|
]
|
|
|
|
|
.padding(20)
|
|
|
|
|
)
|
2024-02-05 00:51:51 +01:00
|
|
|
.on_scroll(|_| Message::Scrolled)
|
2024-07-12 18:12:34 +02:00
|
|
|
.width(Fill)
|
2023-07-27 01:02:47 +02:00
|
|
|
.height(300),
|
|
|
|
|
]
|
|
|
|
|
.padding(20)
|
|
|
|
|
)
|
2024-02-05 00:51:51 +01:00
|
|
|
.on_scroll(|_| Message::Scrolled)
|
2024-07-12 18:12:34 +02:00
|
|
|
.width(Fill)
|
2023-07-27 01:02:47 +02:00
|
|
|
.height(300),
|
|
|
|
|
]
|
|
|
|
|
.spacing(10)
|
|
|
|
|
.padding(20)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn subscription(&self) -> Subscription<Message> {
|
2024-06-04 23:20:33 +02:00
|
|
|
event::listen_with(|event, _status, _window| match event {
|
2023-07-27 01:02:47 +02:00
|
|
|
Event::Mouse(mouse::Event::CursorMoved { position }) => {
|
|
|
|
|
Some(Message::MouseMoved(position))
|
|
|
|
|
}
|
2024-06-04 23:20:33 +02:00
|
|
|
Event::Window(window::Event::Resized { .. }) => {
|
2023-07-27 01:29:20 +02:00
|
|
|
Some(Message::WindowResized)
|
|
|
|
|
}
|
2023-07-27 01:02:47 +02:00
|
|
|
_ => None,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-17 22:56:58 +02:00
|
|
|
const OUTER_CONTAINER: widget::Id = widget::Id::new("outer");
|
|
|
|
|
const INNER_CONTAINER: widget::Id = widget::Id::new("inner");
|