summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-10-25 03:47:34 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-10-25 03:47:34 +0200
commit719c073fc67c87d6b2da1bc01b74751d3f5e59f0 (patch)
tree660613d215cafc01a30911c22a5ba107fb61b12c /native
parent4769272122e8cd0a4d666bb06c00cb27f8cad3c4 (diff)
downloadiced-719c073fc67c87d6b2da1bc01b74751d3f5e59f0.tar.gz
iced-719c073fc67c87d6b2da1bc01b74751d3f5e59f0.tar.bz2
iced-719c073fc67c87d6b2da1bc01b74751d3f5e59f0.zip
Draft `Scrollable` widget (no clipping yet!)
Diffstat (limited to 'native')
-rw-r--r--native/src/user_interface.rs2
-rw-r--r--native/src/widget.rs3
-rw-r--r--native/src/widget/scrollable.rs121
3 files changed, 125 insertions, 1 deletions
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs
index 5675076d..5df0dc6a 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -347,7 +347,7 @@ impl Cache {
.0
.compute_layout(geometry::Size::undefined())
.unwrap(),
- cursor_position: Point::new(0.0, 0.0),
+ cursor_position: Point::new(-1.0, -1.0),
}
}
}
diff --git a/native/src/widget.rs b/native/src/widget.rs
index bcef2665..0d3f6d2c 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -26,6 +26,7 @@ pub mod column;
pub mod image;
pub mod radio;
pub mod row;
+pub mod scrollable;
pub mod slider;
pub mod text;
@@ -42,6 +43,8 @@ pub use radio::Radio;
#[doc(no_inline)]
pub use row::Row;
#[doc(no_inline)]
+pub use scrollable::Scrollable;
+#[doc(no_inline)]
pub use slider::Slider;
#[doc(no_inline)]
pub use text::Text;
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs
new file mode 100644
index 00000000..4644282b
--- /dev/null
+++ b/native/src/widget/scrollable.rs
@@ -0,0 +1,121 @@
+use crate::{
+ column, input::mouse, Element, Event, Hasher, Layout, Node, Point, Style,
+ Widget,
+};
+
+pub use iced_core::scrollable::State;
+
+/// A scrollable [`Column`].
+///
+/// [`Column`]: ../column/struct.Column.html
+pub type Scrollable<'a, Message, Renderer> =
+ iced_core::Scrollable<'a, Element<'a, Message, Renderer>>;
+
+impl<'a, Message, Renderer> Widget<Message, Renderer>
+ for Scrollable<'a, Message, Renderer>
+where
+ Renderer: self::Renderer + column::Renderer,
+{
+ fn node(&self, renderer: &Renderer) -> Node {
+ let mut content = self.content.node(renderer);
+
+ {
+ let mut style = content.0.style();
+ style.flex_shrink = 0.0;
+
+ content.0.set_style(style);
+ }
+
+ let mut style = Style::default()
+ .width(self.content.width)
+ .max_width(self.content.max_width)
+ .height(self.height)
+ .align_self(self.align_self)
+ .align_items(self.align_items);
+
+ style.0.flex_direction = stretch::style::FlexDirection::Column;
+
+ Node::with_children(style, vec![content])
+ }
+
+ fn on_event(
+ &mut self,
+ event: Event,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ messages: &mut Vec<Message>,
+ ) {
+ let bounds = layout.bounds();
+ let is_mouse_over = bounds.contains(cursor_position);
+
+ let content = layout.children().next().unwrap();
+ let content_bounds = content.bounds();
+
+ if is_mouse_over {
+ match event {
+ Event::Mouse(mouse::Event::WheelScrolled {
+ delta_y, ..
+ }) => {
+ // TODO: Configurable speed (?)
+ self.state.offset = (self.state.offset as i32
+ - delta_y.round() as i32 * 15)
+ .max(0)
+ .min((content_bounds.height - bounds.height) as i32)
+ as u32;
+ }
+ _ => {}
+ }
+ }
+
+ let cursor_position = if is_mouse_over {
+ Point::new(
+ cursor_position.x,
+ cursor_position.y + self.state.offset as f32,
+ )
+ } else {
+ Point::new(cursor_position.x, -1.0)
+ };
+
+ self.content.on_event(
+ event,
+ layout.children().next().unwrap(),
+ cursor_position,
+ messages,
+ )
+ }
+
+ fn draw(
+ &self,
+ renderer: &mut Renderer,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ ) -> Renderer::Output {
+ self::Renderer::draw(renderer, &self, layout, cursor_position)
+ }
+
+ fn hash_layout(&self, state: &mut Hasher) {
+ self.content.hash_layout(state)
+ }
+}
+
+pub trait Renderer: crate::Renderer + Sized {
+ fn draw<Message>(
+ &mut self,
+ scrollable: &Scrollable<'_, Message, Self>,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ ) -> Self::Output;
+}
+
+impl<'a, Message, Renderer> From<Scrollable<'a, Message, Renderer>>
+ for Element<'a, Message, Renderer>
+where
+ Renderer: 'a + self::Renderer + column::Renderer,
+ Message: 'static,
+{
+ fn from(
+ scrollable: Scrollable<'a, Message, Renderer>,
+ ) -> Element<'a, Message, Renderer> {
+ Element::new(scrollable)
+ }
+}