Implement float widget interactivity
This commit is contained in:
parent
97b4ed0d84
commit
f8f2e55f19
2 changed files with 94 additions and 19 deletions
|
|
@ -210,6 +210,7 @@ fn card<'a>(
|
||||||
.content_fit(ContentFit::Cover)
|
.content_fit(ContentFit::Cover)
|
||||||
.opacity(thumbnail.fade_in.interpolate(0.0, 1.0, now)),
|
.opacity(thumbnail.fade_in.interpolate(0.0, 1.0, now)),
|
||||||
)
|
)
|
||||||
|
.opaque(false)
|
||||||
.scale(thumbnail.zoom.interpolate(1.0, 1.1, now))
|
.scale(thumbnail.zoom.interpolate(1.0, 1.1, now))
|
||||||
.translate(move |bounds, viewport| {
|
.translate(move |bounds, viewport| {
|
||||||
bounds.zoom(1.1).offset(&viewport.shrink(10))
|
bounds.zoom(1.1).offset(&viewport.shrink(10))
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ where
|
||||||
content: content.into(),
|
content: content.into(),
|
||||||
scale: 1.0,
|
scale: 1.0,
|
||||||
translate: None,
|
translate: None,
|
||||||
opaque: false,
|
opaque: true,
|
||||||
class: Theme::default(),
|
class: Theme::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,6 +134,10 @@ where
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
if self.is_floating(layout.bounds(), *viewport) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.content.as_widget_mut().update(
|
self.content.as_widget_mut().update(
|
||||||
state, event, layout, cursor, renderer, clipboard, shell, viewport,
|
state, event, layout, cursor, renderer, clipboard, shell, viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -181,6 +185,10 @@ where
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
|
if self.is_floating(layout.bounds(), *viewport) {
|
||||||
|
return mouse::Interaction::None;
|
||||||
|
}
|
||||||
|
|
||||||
self.content
|
self.content
|
||||||
.as_widget()
|
.as_widget()
|
||||||
.mouse_interaction(state, layout, cursor, viewport, renderer)
|
.mouse_interaction(state, layout, cursor, viewport, renderer)
|
||||||
|
|
@ -215,13 +223,23 @@ where
|
||||||
.unwrap_or(Vector::ZERO);
|
.unwrap_or(Vector::ZERO);
|
||||||
|
|
||||||
if self.scale > 1.0 || translation != Vector::ZERO {
|
if self.scale > 1.0 || translation != Vector::ZERO {
|
||||||
|
let translation = translation + offset;
|
||||||
|
|
||||||
|
let transformation = Transformation::translate(
|
||||||
|
bounds.x + bounds.width / 2.0 + translation.x,
|
||||||
|
bounds.y + bounds.height / 2.0 + translation.y,
|
||||||
|
) * Transformation::scale(self.scale)
|
||||||
|
* Transformation::translate(
|
||||||
|
-bounds.x - bounds.width / 2.0,
|
||||||
|
-bounds.y - bounds.height / 2.0,
|
||||||
|
);
|
||||||
|
|
||||||
Some(overlay::Element::new(Box::new(Overlay {
|
Some(overlay::Element::new(Box::new(Overlay {
|
||||||
float: self,
|
float: self,
|
||||||
state,
|
state,
|
||||||
layout,
|
layout,
|
||||||
viewport: *viewport,
|
viewport: *viewport,
|
||||||
bounds,
|
transformation,
|
||||||
translation: translation + offset,
|
|
||||||
})))
|
})))
|
||||||
} else {
|
} else {
|
||||||
self.content
|
self.content
|
||||||
|
|
@ -247,12 +265,11 @@ struct Overlay<'a, 'b, Message, Theme, Renderer>
|
||||||
where
|
where
|
||||||
Theme: Catalog,
|
Theme: Catalog,
|
||||||
{
|
{
|
||||||
float: &'a Float<'b, Message, Theme, Renderer>,
|
float: &'a mut Float<'b, Message, Theme, Renderer>,
|
||||||
state: &'a mut widget::Tree,
|
state: &'a mut widget::Tree,
|
||||||
layout: Layout<'a>,
|
layout: Layout<'a>,
|
||||||
viewport: Rectangle,
|
viewport: Rectangle,
|
||||||
bounds: Rectangle,
|
transformation: Transformation,
|
||||||
translation: Vector,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Message, Theme, Renderer> core::Overlay<Message, Theme, Renderer>
|
impl<Message, Theme, Renderer> core::Overlay<Message, Theme, Renderer>
|
||||||
|
|
@ -262,7 +279,9 @@ where
|
||||||
Renderer: core::Renderer,
|
Renderer: core::Renderer,
|
||||||
{
|
{
|
||||||
fn layout(&mut self, _renderer: &Renderer, _bounds: Size) -> layout::Node {
|
fn layout(&mut self, _renderer: &Renderer, _bounds: Size) -> layout::Node {
|
||||||
layout::Node::new(self.bounds.size()).move_to(self.bounds.position())
|
let bounds = self.layout.bounds();
|
||||||
|
|
||||||
|
layout::Node::new(bounds.size()).move_to(bounds.position())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_over(
|
fn is_over(
|
||||||
|
|
@ -271,7 +290,33 @@ where
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.float.opaque && layout.bounds().contains(cursor_position)
|
self.float.opaque
|
||||||
|
&& layout
|
||||||
|
.bounds()
|
||||||
|
.contains(cursor_position * self.transformation.inverse())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
event: &Event,
|
||||||
|
_layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
renderer: &Renderer,
|
||||||
|
clipboard: &mut dyn Clipboard,
|
||||||
|
shell: &mut Shell<'_, Message>,
|
||||||
|
) {
|
||||||
|
let cursor = cursor * self.transformation.inverse();
|
||||||
|
|
||||||
|
self.float.content.as_widget_mut().update(
|
||||||
|
self.state,
|
||||||
|
event,
|
||||||
|
self.layout,
|
||||||
|
cursor,
|
||||||
|
renderer,
|
||||||
|
clipboard,
|
||||||
|
shell,
|
||||||
|
&self.viewport,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
|
|
@ -284,17 +329,8 @@ where
|
||||||
) {
|
) {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
||||||
let transformation = Transformation::translate(
|
|
||||||
bounds.x + bounds.width / 2.0 + self.translation.x,
|
|
||||||
bounds.y + bounds.height / 2.0 + self.translation.y,
|
|
||||||
) * Transformation::scale(self.float.scale)
|
|
||||||
* Transformation::translate(
|
|
||||||
-bounds.x - bounds.width / 2.0,
|
|
||||||
-bounds.y - bounds.height / 2.0,
|
|
||||||
);
|
|
||||||
|
|
||||||
renderer.with_layer(self.viewport, |renderer| {
|
renderer.with_layer(self.viewport, |renderer| {
|
||||||
renderer.with_transformation(transformation, |renderer| {
|
renderer.with_transformation(self.transformation, |renderer| {
|
||||||
{
|
{
|
||||||
let style = theme.style(&self.float.class);
|
let style = theme.style(&self.float.class);
|
||||||
|
|
||||||
|
|
@ -319,15 +355,53 @@ where
|
||||||
style,
|
style,
|
||||||
self.layout,
|
self.layout,
|
||||||
cursor,
|
cursor,
|
||||||
&(self.viewport * transformation.inverse()),
|
&(self.viewport * self.transformation.inverse()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mouse_interaction(
|
||||||
|
&self,
|
||||||
|
_layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
_viewport: &Rectangle,
|
||||||
|
renderer: &Renderer,
|
||||||
|
) -> mouse::Interaction {
|
||||||
|
self.float.content.as_widget().mouse_interaction(
|
||||||
|
self.state,
|
||||||
|
self.layout,
|
||||||
|
cursor * self.transformation.inverse(),
|
||||||
|
&self.viewport,
|
||||||
|
renderer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn index(&self) -> f32 {
|
fn index(&self) -> f32 {
|
||||||
self.float.scale * 0.5
|
self.float.scale * 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn operate(
|
||||||
|
&mut self,
|
||||||
|
_layout: Layout<'_>,
|
||||||
|
_renderer: &Renderer,
|
||||||
|
_operation: &mut dyn widget::Operation,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlay<'a>(
|
||||||
|
&'a mut self,
|
||||||
|
_layout: Layout<'_>,
|
||||||
|
renderer: &Renderer,
|
||||||
|
) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
|
||||||
|
self.float.content.as_widget_mut().overlay(
|
||||||
|
self.state,
|
||||||
|
self.layout,
|
||||||
|
renderer,
|
||||||
|
&self.viewport,
|
||||||
|
self.transformation.translation(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The theme catalog of a [`Float`].
|
/// The theme catalog of a [`Float`].
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue