summaryrefslogtreecommitdiffstats
path: root/native/src/overlay
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-03-04 05:37:11 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-03-04 05:37:11 +0100
commit3a0d34c0240f4421737a6a08761f99d6f8140d02 (patch)
treec9a4a6b8e9c1db1b8fcd05bc98e3f131d5ef4bd5 /native/src/overlay
parentc54409d1711e1f615c7ea4b02c082954e340632a (diff)
downloadiced-3a0d34c0240f4421737a6a08761f99d6f8140d02.tar.gz
iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.tar.bz2
iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.zip
Create `iced_widget` subcrate and re-organize the whole codebase
Diffstat (limited to 'native/src/overlay')
-rw-r--r--native/src/overlay/element.rs270
-rw-r--r--native/src/overlay/group.rs174
-rw-r--r--native/src/overlay/menu.rs519
3 files changed, 0 insertions, 963 deletions
diff --git a/native/src/overlay/element.rs b/native/src/overlay/element.rs
deleted file mode 100644
index 237d25d1..00000000
--- a/native/src/overlay/element.rs
+++ /dev/null
@@ -1,270 +0,0 @@
-pub use crate::Overlay;
-
-use crate::event::{self, Event};
-use crate::layout;
-use crate::mouse;
-use crate::renderer;
-use crate::widget;
-use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size, Vector};
-
-use std::any::Any;
-
-/// A generic [`Overlay`].
-#[allow(missing_debug_implementations)]
-pub struct Element<'a, Message, Renderer> {
- position: Point,
- overlay: Box<dyn Overlay<Message, Renderer> + 'a>,
-}
-
-impl<'a, Message, Renderer> Element<'a, Message, Renderer>
-where
- Renderer: crate::Renderer,
-{
- /// Creates a new [`Element`] containing the given [`Overlay`].
- pub fn new(
- position: Point,
- overlay: Box<dyn Overlay<Message, Renderer> + 'a>,
- ) -> Self {
- Self { position, overlay }
- }
-
- /// Returns the position of the [`Element`].
- pub fn position(&self) -> Point {
- self.position
- }
-
- /// Translates the [`Element`].
- pub fn translate(mut self, translation: Vector) -> Self {
- self.position = self.position + translation;
- self
- }
-
- /// Applies a transformation to the produced message of the [`Element`].
- pub fn map<B>(self, f: &'a dyn Fn(Message) -> B) -> Element<'a, B, Renderer>
- where
- Message: 'a,
- Renderer: 'a,
- B: 'a,
- {
- Element {
- position: self.position,
- overlay: Box::new(Map::new(self.overlay, f)),
- }
- }
-
- /// Computes the layout of the [`Element`] in the given bounds.
- pub fn layout(
- &self,
- renderer: &Renderer,
- bounds: Size,
- translation: Vector,
- ) -> layout::Node {
- self.overlay
- .layout(renderer, bounds, self.position + translation)
- }
-
- /// Processes a runtime [`Event`].
- pub fn on_event(
- &mut self,
- event: Event,
- layout: Layout<'_>,
- cursor_position: Point,
- renderer: &Renderer,
- clipboard: &mut dyn Clipboard,
- shell: &mut Shell<'_, Message>,
- ) -> event::Status {
- self.overlay.on_event(
- event,
- layout,
- cursor_position,
- renderer,
- clipboard,
- shell,
- )
- }
-
- /// Returns the current [`mouse::Interaction`] of the [`Element`].
- pub fn mouse_interaction(
- &self,
- layout: Layout<'_>,
- cursor_position: Point,
- viewport: &Rectangle,
- renderer: &Renderer,
- ) -> mouse::Interaction {
- self.overlay.mouse_interaction(
- layout,
- cursor_position,
- viewport,
- renderer,
- )
- }
-
- /// Draws the [`Element`] and its children using the given [`Layout`].
- pub fn draw(
- &self,
- renderer: &mut Renderer,
- theme: &Renderer::Theme,
- style: &renderer::Style,
- layout: Layout<'_>,
- cursor_position: Point,
- ) {
- self.overlay
- .draw(renderer, theme, style, layout, cursor_position)
- }
-
- /// Applies a [`widget::Operation`] to the [`Element`].
- pub fn operate(
- &mut self,
- layout: Layout<'_>,
- renderer: &Renderer,
- operation: &mut dyn widget::Operation<Message>,
- ) {
- self.overlay.operate(layout, renderer, operation);
- }
-
- /// Returns true if the cursor is over the [`Element`].
- pub fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool {
- self.overlay.is_over(layout, cursor_position)
- }
-}
-
-struct Map<'a, A, B, Renderer> {
- content: Box<dyn Overlay<A, Renderer> + 'a>,
- mapper: &'a dyn Fn(A) -> B,
-}
-
-impl<'a, A, B, Renderer> Map<'a, A, B, Renderer> {
- pub fn new(
- content: Box<dyn Overlay<A, Renderer> + 'a>,
- mapper: &'a dyn Fn(A) -> B,
- ) -> Map<'a, A, B, Renderer> {
- Map { content, mapper }
- }
-}
-
-impl<'a, A, B, Renderer> Overlay<B, Renderer> for Map<'a, A, B, Renderer>
-where
- Renderer: crate::Renderer,
-{
- fn layout(
- &self,
- renderer: &Renderer,
- bounds: Size,
- position: Point,
- ) -> layout::Node {
- self.content.layout(renderer, bounds, position)
- }
-
- fn operate(
- &mut self,
- layout: Layout<'_>,
- renderer: &Renderer,
- operation: &mut dyn widget::Operation<B>,
- ) {
- struct MapOperation<'a, B> {
- operation: &'a mut dyn widget::Operation<B>,
- }
-
- impl<'a, T, B> widget::Operation<T> for MapOperation<'a, B> {
- fn container(
- &mut self,
- id: Option<&widget::Id>,
- operate_on_children: &mut dyn FnMut(
- &mut dyn widget::Operation<T>,
- ),
- ) {
- self.operation.container(id, &mut |operation| {
- operate_on_children(&mut MapOperation { operation });
- });
- }
-
- fn focusable(
- &mut self,
- state: &mut dyn widget::operation::Focusable,
- id: Option<&widget::Id>,
- ) {
- self.operation.focusable(state, id);
- }
-
- fn scrollable(
- &mut self,
- state: &mut dyn widget::operation::Scrollable,
- id: Option<&widget::Id>,
- ) {
- self.operation.scrollable(state, id);
- }
-
- fn text_input(
- &mut self,
- state: &mut dyn widget::operation::TextInput,
- id: Option<&widget::Id>,
- ) {
- self.operation.text_input(state, id)
- }
-
- fn custom(&mut self, state: &mut dyn Any, id: Option<&widget::Id>) {
- self.operation.custom(state, id);
- }
- }
-
- self.content
- .operate(layout, renderer, &mut MapOperation { operation });
- }
-
- fn on_event(
- &mut self,
- event: Event,
- layout: Layout<'_>,
- cursor_position: Point,
- renderer: &Renderer,
- clipboard: &mut dyn Clipboard,
- shell: &mut Shell<'_, B>,
- ) -> event::Status {
- let mut local_messages = Vec::new();
- let mut local_shell = Shell::new(&mut local_messages);
-
- let event_status = self.content.on_event(
- event,
- layout,
- cursor_position,
- renderer,
- clipboard,
- &mut local_shell,
- );
-
- shell.merge(local_shell, self.mapper);
-
- event_status
- }
-
- fn mouse_interaction(
- &self,
- layout: Layout<'_>,
- cursor_position: Point,
- viewport: &Rectangle,
- renderer: &Renderer,
- ) -> mouse::Interaction {
- self.content.mouse_interaction(
- layout,
- cursor_position,
- viewport,
- renderer,
- )
- }
-
- fn draw(
- &self,
- renderer: &mut Renderer,
- theme: &Renderer::Theme,
- style: &renderer::Style,
- layout: Layout<'_>,
- cursor_position: Point,
- ) {
- self.content
- .draw(renderer, theme, style, layout, cursor_position)
- }
-
- fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool {
- self.content.is_over(layout, cursor_position)
- }
-}
diff --git a/native/src/overlay/group.rs b/native/src/overlay/group.rs
deleted file mode 100644
index 1126f0cf..00000000
--- a/native/src/overlay/group.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-use iced_core::{Point, Rectangle, Size};
-
-use crate::event;
-use crate::layout;
-use crate::mouse;
-use crate::overlay;
-use crate::renderer;
-use crate::widget;
-use crate::{Clipboard, Event, Layout, Overlay, Shell};
-
-/// An [`Overlay`] container that displays multiple overlay [`overlay::Element`]
-/// children.
-#[allow(missing_debug_implementations)]
-pub struct Group<'a, Message, Renderer> {
- children: Vec<overlay::Element<'a, Message, Renderer>>,
-}
-
-impl<'a, Message, Renderer> Group<'a, Message, Renderer>
-where
- Renderer: 'a + crate::Renderer,
- Message: 'a,
-{
- /// Creates an empty [`Group`].
- pub fn new() -> Self {
- Self::default()
- }
-
- /// Creates a [`Group`] with the given elements.
- pub fn with_children(
- children: Vec<overlay::Element<'a, Message, Renderer>>,
- ) -> Self {
- Group { children }
- }
-
- /// Adds an [`overlay::Element`] to the [`Group`].
- pub fn push(
- mut self,
- child: impl Into<overlay::Element<'a, Message, Renderer>>,
- ) -> Self {
- self.children.push(child.into());
- self
- }
-
- /// Turns the [`Group`] into an overlay [`overlay::Element`].
- pub fn overlay(self) -> overlay::Element<'a, Message, Renderer> {
- overlay::Element::new(Point::ORIGIN, Box::new(self))
- }
-}
-
-impl<'a, Message, Renderer> Default for Group<'a, Message, Renderer>
-where
- Renderer: 'a + crate::Renderer,
- Message: 'a,
-{
- fn default() -> Self {
- Self::with_children(Vec::new())
- }
-}
-
-impl<'a, Message, Renderer> Overlay<Message, Renderer>
- for Group<'a, Message, Renderer>
-where
- Renderer: crate::Renderer,
-{
- fn layout(
- &self,
- renderer: &Renderer,
- bounds: Size,
- position: Point,
- ) -> layout::Node {
- let translation = position - Point::ORIGIN;
-
- layout::Node::with_children(
- bounds,
- self.children
- .iter()
- .map(|child| child.layout(renderer, bounds, translation))
- .collect(),
- )
- }
-
- fn on_event(
- &mut self,
- event: Event,
- layout: Layout<'_>,
- cursor_position: Point,
- renderer: &Renderer,
- clipboard: &mut dyn Clipboard,
- shell: &mut Shell<'_, Message>,
- ) -> event::Status {
- self.children
- .iter_mut()
- .zip(layout.children())
- .map(|(child, layout)| {
- child.on_event(
- event.clone(),
- layout,
- cursor_position,
- renderer,
- clipboard,
- shell,
- )
- })
- .fold(event::Status::Ignored, event::Status::merge)
- }
-
- fn draw(
- &self,
- renderer: &mut Renderer,
- theme: &<Renderer as crate::Renderer>::Theme,
- style: &renderer::Style,
- layout: Layout<'_>,
- cursor_position: Point,
- ) {
- for (child, layout) in self.children.iter().zip(layout.children()) {
- child.draw(renderer, theme, style, layout, cursor_position);
- }
- }
-
- fn mouse_interaction(
- &self,
- layout: Layout<'_>,
- cursor_position: Point,
- viewport: &Rectangle,
- renderer: &Renderer,
- ) -> mouse::Interaction {
- self.children
- .iter()
- .zip(layout.children())
- .map(|(child, layout)| {
- child.mouse_interaction(
- layout,
- cursor_position,
- viewport,
- renderer,
- )
- })
- .max()
- .unwrap_or_default()
- }
-
- fn operate(
- &mut self,
- layout: Layout<'_>,
- renderer: &Renderer,
- operation: &mut dyn widget::Operation<Message>,
- ) {
- operation.container(None, &mut |operation| {
- self.children.iter_mut().zip(layout.children()).for_each(
- |(child, layout)| {
- child.operate(layout, renderer, operation);
- },
- )
- });
- }
-
- fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool {
- self.children
- .iter()
- .zip(layout.children())
- .any(|(child, layout)| child.is_over(layout, cursor_position))
- }
-}
-
-impl<'a, Message, Renderer> From<Group<'a, Message, Renderer>>
- for overlay::Element<'a, Message, Renderer>
-where
- Renderer: 'a + crate::Renderer,
- Message: 'a,
-{
- fn from(group: Group<'a, Message, Renderer>) -> Self {
- group.overlay()
- }
-}
diff --git a/native/src/overlay/menu.rs b/native/src/overlay/menu.rs
deleted file mode 100644
index bd58a122..00000000
--- a/native/src/overlay/menu.rs
+++ /dev/null
@@ -1,519 +0,0 @@
-//! Build and show dropdown menus.
-use crate::alignment;
-use crate::event::{self, Event};
-use crate::layout;
-use crate::mouse;
-use crate::overlay;
-use crate::renderer;
-use crate::text::{self, Text};
-use crate::touch;
-use crate::widget::container::{self, Container};
-use crate::widget::scrollable::{self, Scrollable};
-use crate::widget::Tree;
-use crate::{
- Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point,
- Rectangle, Shell, Size, Vector, Widget,
-};
-
-pub use iced_style::menu::{Appearance, StyleSheet};
-
-/// A list of selectable options.
-#[allow(missing_debug_implementations)]
-pub struct Menu<'a, T, Renderer>
-where
- Renderer: text::Renderer,
- Renderer::Theme: StyleSheet,
-{
- state: &'a mut State,
- options: &'a [T],
- hovered_option: &'a mut Option<usize>,
- last_selection: &'a mut Option<T>,
- width: f32,
- padding: Padding,
- text_size: Option<f32>,
- font: Option<Renderer::Font>,
- style: <Renderer::Theme as StyleSheet>::Style,
-}
-
-impl<'a, T, Renderer> Menu<'a, T, Renderer>
-where
- T: ToString + Clone,
- Renderer: text::Renderer + 'a,
- Renderer::Theme:
- StyleSheet + container::StyleSheet + scrollable::StyleSheet,
-{
- /// Creates a new [`Menu`] with the given [`State`], a list of options, and
- /// the message to produced when an option is selected.
- pub fn new(
- state: &'a mut State,
- options: &'a [T],
- hovered_option: &'a mut Option<usize>,
- last_selection: &'a mut Option<T>,
- ) -> Self {
- Menu {
- state,
- options,
- hovered_option,
- last_selection,
- width: 0.0,
- padding: Padding::ZERO,
- text_size: None,
- font: None,
- style: Default::default(),
- }
- }
-
- /// Sets the width of the [`Menu`].
- pub fn width(mut self, width: f32) -> Self {
- self.width = width;
- self
- }
-
- /// Sets the [`Padding`] of the [`Menu`].
- pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
- self.padding = padding.into();
- self
- }
-
- /// Sets the text size of the [`Menu`].
- pub fn text_size(mut self, text_size: impl Into<Pixels>) -> Self {
- self.text_size = Some(text_size.into().0);
- self
- }
-
- /// Sets the font of the [`Menu`].
- pub fn font(mut self, font: impl Into<Renderer::Font>) -> Self {
- self.font = Some(font.into());
- self
- }
-
- /// Sets the style of the [`Menu`].
- pub fn style(
- mut self,
- style: impl Into<<Renderer::Theme as StyleSheet>::Style>,
- ) -> Self {
- self.style = style.into();
- self
- }
-
- /// Turns the [`Menu`] into an overlay [`Element`] at the given target
- /// position.
- ///
- /// The `target_height` will be used to display the menu either on top
- /// of the target or under it, depending on the screen position and the
- /// dimensions of the [`Menu`].
- pub fn overlay<Message: 'a>(
- self,
- position: Point,
- target_height: f32,
- ) -> overlay::Element<'a, Message, Renderer> {
- overlay::Element::new(
- position,
- Box::new(Overlay::new(self, target_height)),
- )
- }
-}
-
-/// The local state of a [`Menu`].
-#[derive(Debug)]
-pub struct State {
- tree: Tree,
-}
-
-impl State {
- /// Creates a new [`State`] for a [`Menu`].
- pub fn new() -> Self {
- Self {
- tree: Tree::empty(),
- }
- }
-}
-
-impl Default for State {
- fn default() -> Self {
- Self::new()
- }
-}
-
-struct Overlay<'a, Message, Renderer>
-where
- Renderer: crate::Renderer,
- Renderer::Theme: StyleSheet + container::StyleSheet,
-{
- state: &'a mut Tree,
- container: Container<'a, Message, Renderer>,
- width: f32,
- target_height: f32,
- style: <Renderer::Theme as StyleSheet>::Style,
-}
-
-impl<'a, Message, Renderer> Overlay<'a, Message, Renderer>
-where
- Message: 'a,
- Renderer: 'a,
- Renderer: text::Renderer,
- Renderer::Theme:
- StyleSheet + container::StyleSheet + scrollable::StyleSheet,
-{
- pub fn new<T>(menu: Menu<'a, T, Renderer>, target_height: f32) -> Self
- where
- T: Clone + ToString,
- {
- let Menu {
- state,
- options,
- hovered_option,
- last_selection,
- width,
- padding,
- font,
- text_size,
- style,
- } = menu;
-
- let container = Container::new(Scrollable::new(List {
- options,
- hovered_option,
- last_selection,
- font,
- text_size,
- padding,
- style: style.clone(),
- }));
-
- state.tree.diff(&container as &dyn Widget<_, _>);
-
- Self {
- state: &mut state.tree,
- container,
- width,
- target_height,
- style,
- }
- }
-}
-
-impl<'a, Message, Renderer> crate::Overlay<Message, Renderer>
- for Overlay<'a, Message, Renderer>
-where
- Renderer: text::Renderer,
- Renderer::Theme: StyleSheet + container::StyleSheet,
-{
- fn layout(
- &self,
- renderer: &Renderer,
- bounds: Size,
- position: Point,
- ) -> layout::Node {
- let space_below = bounds.height - (position.y + self.target_height);
- let space_above = position.y;
-
- let limits = layout::Limits::new(
- Size::ZERO,
- Size::new(
- bounds.width - position.x,
- if space_below > space_above {
- space_below
- } else {
- space_above
- },
- ),
- )
- .width(self.width);
-
- let mut node = self.container.layout(renderer, &limits);
-
- node.move_to(if space_below > space_above {
- position + Vector::new(0.0, self.target_height)
- } else {
- position - Vector::new(0.0, node.size().height)
- });
-
- node
- }
-
- fn on_event(
- &mut self,
- event: Event,
- layout: Layout<'_>,
- cursor_position: Point,
- renderer: &Renderer,
- clipboard: &mut dyn Clipboard,
- shell: &mut Shell<'_, Message>,
- ) -> event::Status {
- self.container.on_event(
- self.state,
- event,
- layout,
- cursor_position,
- renderer,
- clipboard,
- shell,
- )
- }
-
- fn mouse_interaction(
- &self,
- layout: Layout<'_>,
- cursor_position: Point,
- viewport: &Rectangle,
- renderer: &Renderer,
- ) -> mouse::Interaction {
- self.container.mouse_interaction(
- self.state,
- layout,
- cursor_position,
- viewport,
- renderer,
- )
- }
-
- fn draw(
- &self,
- renderer: &mut Renderer,
- theme: &Renderer::Theme,
- style: &renderer::Style,
- layout: Layout<'_>,
- cursor_position: Point,
- ) {
- let appearance = theme.appearance(&self.style);
- let bounds = layout.bounds();
-
- renderer.fill_quad(
- renderer::Quad {
- bounds,
- border_color: appearance.border_color,
- border_width: appearance.border_width,
- border_radius: appearance.border_radius.into(),
- },
- appearance.background,
- );
-
- self.container.draw(
- self.state,
- renderer,
- theme,
- style,
- layout,
- cursor_position,
- &bounds,
- );
- }
-}
-
-struct List<'a, T, Renderer>
-where
- Renderer: text::Renderer,
- Renderer::Theme: StyleSheet,
-{
- options: &'a [T],
- hovered_option: &'a mut Option<usize>,
- last_selection: &'a mut Option<T>,
- padding: Padding,
- text_size: Option<f32>,
- font: Option<Renderer::Font>,
- style: <Renderer::Theme as StyleSheet>::Style,
-}
-
-impl<'a, T, Message, Renderer> Widget<Message, Renderer>
- for List<'a, T, Renderer>
-where
- T: Clone + ToString,
- Renderer: text::Renderer,
- Renderer::Theme: StyleSheet,
-{
- fn width(&self) -> Length {
- Length::Fill
- }
-
- fn height(&self) -> Length {
- Length::Shrink
- }
-
- fn layout(
- &self,
- renderer: &Renderer,
- limits: &layout::Limits,
- ) -> layout::Node {
- use std::f32;
-
- let limits = limits.width(Length::Fill).height(Length::Shrink);
- let text_size =
- self.text_size.unwrap_or_else(|| renderer.default_size());
-
- let size = {
- let intrinsic = Size::new(
- 0.0,
- (text_size * 1.2 + self.padding.vertical())
- * self.options.len() as f32,
- );
-
- limits.resolve(intrinsic)
- };
-
- layout::Node::new(size)
- }
-
- fn on_event(
- &mut self,
- _state: &mut Tree,
- event: Event,
- layout: Layout<'_>,
- cursor_position: Point,
- renderer: &Renderer,
- _clipboard: &mut dyn Clipboard,
- _shell: &mut Shell<'_, Message>,
- ) -> event::Status {
- match event {
- Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
- let bounds = layout.bounds();
-
- if bounds.contains(cursor_position) {
- if let Some(index) = *self.hovered_option {
- if let Some(option) = self.options.get(index) {
- *self.last_selection = Some(option.clone());
- }
- }
- }
- }
- Event::Mouse(mouse::Event::CursorMoved { .. }) => {
- let bounds = layout.bounds();
-
- if bounds.contains(cursor_position) {
- let text_size = self
- .text_size
- .unwrap_or_else(|| renderer.default_size());
-
- *self.hovered_option = Some(
- ((cursor_position.y - bounds.y)
- / (text_size * 1.2 + self.padding.vertical()))
- as usize,
- );
- }
- }
- Event::Touch(touch::Event::FingerPressed { .. }) => {
- let bounds = layout.bounds();
-
- if bounds.contains(cursor_position) {
- let text_size = self
- .text_size
- .unwrap_or_else(|| renderer.default_size());
-
- *self.hovered_option = Some(
- ((cursor_position.y - bounds.y)
- / (text_size * 1.2 + self.padding.vertical()))
- as usize,
- );
-
- if let Some(index) = *self.hovered_option {
- if let Some(option) = self.options.get(index) {
- *self.last_selection = Some(option.clone());
- }
- }
- }
- }
- _ => {}
- }
-
- event::Status::Ignored
- }
-
- fn mouse_interaction(
- &self,
- _state: &Tree,
- layout: Layout<'_>,
- cursor_position: Point,
- _viewport: &Rectangle,
- _renderer: &Renderer,
- ) -> mouse::Interaction {
- let is_mouse_over = layout.bounds().contains(cursor_position);
-
- if is_mouse_over {
- mouse::Interaction::Pointer
- } else {
- mouse::Interaction::default()
- }
- }
-
- fn draw(
- &self,
- _state: &Tree,
- renderer: &mut Renderer,
- theme: &Renderer::Theme,
- _style: &renderer::Style,
- layout: Layout<'_>,
- _cursor_position: Point,
- viewport: &Rectangle,
- ) {
- let appearance = theme.appearance(&self.style);
- let bounds = layout.bounds();
-
- let text_size =
- self.text_size.unwrap_or_else(|| renderer.default_size());
- let option_height =
- (text_size * 1.2 + self.padding.vertical()) as usize;
-
- 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 = &self.options[start..end.min(self.options.len())];
-
- for (i, option) in visible_options.iter().enumerate() {
- let i = start + i;
- let is_selected = *self.hovered_option == Some(i);
-
- let bounds = Rectangle {
- x: bounds.x,
- y: bounds.y + (option_height * i) as f32,
- width: bounds.width,
- height: text_size * 1.2 + self.padding.vertical(),
- };
-
- if is_selected {
- renderer.fill_quad(
- renderer::Quad {
- bounds,
- border_color: Color::TRANSPARENT,
- border_width: 0.0,
- border_radius: appearance.border_radius.into(),
- },
- appearance.selected_background,
- );
- }
-
- renderer.fill_text(Text {
- content: &option.to_string(),
- bounds: Rectangle {
- x: bounds.x + self.padding.left,
- y: bounds.center_y(),
- width: f32::INFINITY,
- ..bounds
- },
- size: text_size,
- font: self.font.unwrap_or_else(|| renderer.default_font()),
- color: if is_selected {
- appearance.selected_text_color
- } else {
- appearance.text_color
- },
- horizontal_alignment: alignment::Horizontal::Left,
- vertical_alignment: alignment::Vertical::Center,
- });
- }
- }
-}
-
-impl<'a, T, Message, Renderer> From<List<'a, T, Renderer>>
- for Element<'a, Message, Renderer>
-where
- T: ToString + Clone,
- Message: 'a,
- Renderer: 'a + text::Renderer,
- Renderer::Theme: StyleSheet,
-{
- fn from(list: List<'a, T, Renderer>) -> Self {
- Element::new(list)
- }
-}