From d328b07b3937c968fc8139f0b5c61903ebb893e7 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 18 Aug 2020 03:37:32 +0200 Subject: Introduce `viewport` to `Widget::draw` This should eventually allow us to only generate primitives that are visible. --- graphics/src/renderer.rs | 3 ++- graphics/src/widget/button.rs | 1 + graphics/src/widget/canvas.rs | 5 +++-- graphics/src/widget/column.rs | 12 +++++++++--- graphics/src/widget/container.rs | 10 ++++++++-- graphics/src/widget/pane_grid.rs | 3 ++- graphics/src/widget/row.rs | 12 +++++++++--- 7 files changed, 34 insertions(+), 12 deletions(-) (limited to 'graphics') diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 5d51e6d4..a880e22a 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -96,10 +96,11 @@ where widget: &dyn Widget, layout: Layout<'_>, cursor_position: Point, + viewport: &Rectangle, color: Color, ) -> Self::Output { let (primitive, cursor) = - widget.draw(self, defaults, layout, cursor_position); + widget.draw(self, defaults, layout, cursor_position, viewport); let mut primitives = Vec::new(); diff --git a/graphics/src/widget/button.rs b/graphics/src/widget/button.rs index ecabc868..a1afc940 100644 --- a/graphics/src/widget/button.rs +++ b/graphics/src/widget/button.rs @@ -62,6 +62,7 @@ where }, content_layout, cursor_position, + &bounds, ); ( diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index bc0802e5..73778d16 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -8,8 +8,8 @@ //! [`Frame`]: struct.Frame.html use crate::{Backend, Defaults, Primitive, Renderer}; use iced_native::{ - layout, mouse, Clipboard, Element, Hasher, Layout, Length, Point, Size, - Vector, Widget, + layout, mouse, Clipboard, Element, Hasher, Layout, Length, Point, + Rectangle, Size, Vector, Widget, }; use std::hash::Hash; use std::marker::PhantomData; @@ -196,6 +196,7 @@ where _defaults: &Defaults, layout: Layout<'_>, cursor_position: Point, + _viewport: &Rectangle, ) -> (Primitive, mouse::Interaction) { let bounds = layout.bounds(); let translation = Vector::new(bounds.x, bounds.y); diff --git a/graphics/src/widget/column.rs b/graphics/src/widget/column.rs index 6c7235c7..0cf56842 100644 --- a/graphics/src/widget/column.rs +++ b/graphics/src/widget/column.rs @@ -1,7 +1,7 @@ use crate::{Backend, Primitive, Renderer}; use iced_native::column; use iced_native::mouse; -use iced_native::{Element, Layout, Point}; +use iced_native::{Element, Layout, Point, Rectangle}; /// A container that distributes its contents vertically. pub type Column<'a, Message, Backend> = @@ -17,6 +17,7 @@ where content: &[Element<'_, Message, Self>], layout: Layout<'_>, cursor_position: Point, + viewport: &Rectangle, ) -> Self::Output { let mut mouse_interaction = mouse::Interaction::default(); @@ -26,8 +27,13 @@ where .iter() .zip(layout.children()) .map(|(child, layout)| { - let (primitive, new_mouse_interaction) = - child.draw(self, defaults, layout, cursor_position); + let (primitive, new_mouse_interaction) = child.draw( + self, + defaults, + layout, + cursor_position, + viewport, + ); if new_mouse_interaction > mouse_interaction { mouse_interaction = new_mouse_interaction; diff --git a/graphics/src/widget/container.rs b/graphics/src/widget/container.rs index 5b3a01d2..4854f589 100644 --- a/graphics/src/widget/container.rs +++ b/graphics/src/widget/container.rs @@ -24,6 +24,7 @@ where defaults: &Defaults, bounds: Rectangle, cursor_position: Point, + viewport: &Rectangle, style_sheet: &Self::Style, content: &Element<'_, Message, Self>, content_layout: Layout<'_>, @@ -36,8 +37,13 @@ where }, }; - let (content, mouse_interaction) = - content.draw(self, &defaults, content_layout, cursor_position); + let (content, mouse_interaction) = content.draw( + self, + &defaults, + content_layout, + cursor_position, + viewport, + ); if let Some(background) = background(bounds, &style) { ( diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs index aa8a3f7c..5b0eb391 100644 --- a/graphics/src/widget/pane_grid.rs +++ b/graphics/src/widget/pane_grid.rs @@ -137,7 +137,7 @@ where let (body, body_layout) = body; let (body_primitive, body_interaction) = - body.draw(self, defaults, body_layout, cursor_position); + body.draw(self, defaults, body_layout, cursor_position, &bounds); let background = crate::widget::container::background(bounds, &style); @@ -224,6 +224,7 @@ where &defaults, controls_layout, cursor_position, + &bounds, ); ( diff --git a/graphics/src/widget/row.rs b/graphics/src/widget/row.rs index 4c1dbadc..397d80bf 100644 --- a/graphics/src/widget/row.rs +++ b/graphics/src/widget/row.rs @@ -1,7 +1,7 @@ use crate::{Backend, Primitive, Renderer}; use iced_native::mouse; use iced_native::row; -use iced_native::{Element, Layout, Point}; +use iced_native::{Element, Layout, Point, Rectangle}; /// A container that distributes its contents horizontally. pub type Row<'a, Message, Backend> = @@ -17,6 +17,7 @@ where content: &[Element<'_, Message, Self>], layout: Layout<'_>, cursor_position: Point, + viewport: &Rectangle, ) -> Self::Output { let mut mouse_interaction = mouse::Interaction::default(); @@ -26,8 +27,13 @@ where .iter() .zip(layout.children()) .map(|(child, layout)| { - let (primitive, new_mouse_interaction) = - child.draw(self, defaults, layout, cursor_position); + let (primitive, new_mouse_interaction) = child.draw( + self, + defaults, + layout, + cursor_position, + viewport, + ); if new_mouse_interaction > mouse_interaction { mouse_interaction = new_mouse_interaction; -- cgit From 7f0276521447c36a3a6026fccc9abdb6e064132c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 18 Aug 2020 04:12:23 +0200 Subject: Draw only visible options in `overlay::Menu` --- graphics/src/overlay/menu.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'graphics') diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs index a952f065..f42c5e3c 100644 --- a/graphics/src/overlay/menu.rs +++ b/graphics/src/overlay/menu.rs @@ -42,6 +42,7 @@ where &mut self, bounds: Rectangle, cursor_position: Point, + viewport: &Rectangle, options: &[T], hovered_option: Option, padding: u16, @@ -52,16 +53,24 @@ where use std::f32; let is_mouse_over = bounds.contains(cursor_position); + let option_height = text_size as usize + padding as usize * 2; let mut primitives = Vec::new(); - for (i, option) in options.iter().enumerate() { + let offset = viewport.y - bounds.y; + let start = (offset / option_height as f32) as usize; + let end = + ((offset + viewport.height) / option_height as f32).ceil() as usize; + + let visible_options = &options[start..end.min(options.len())]; + + for (i, option) in visible_options.iter().enumerate() { + let i = start + i; let is_selected = hovered_option == Some(i); let bounds = Rectangle { x: bounds.x, - y: bounds.y - + ((text_size as usize + padding as usize * 2) * i) as f32, + y: bounds.y + (option_height * i) as f32, width: bounds.width, height: f32::from(text_size + padding * 2), }; -- cgit