Draft new layout API
This commit is contained in:
parent
839e039dbf
commit
2303111e09
30 changed files with 247 additions and 596 deletions
|
|
@ -9,6 +9,5 @@ repository = "https://github.com/hecrj/iced"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced_core = { version = "0.1.0-alpha", path = "../core" }
|
iced_core = { version = "0.1.0-alpha", path = "../core" }
|
||||||
stretch = "0.2"
|
|
||||||
twox-hash = "1.5"
|
twox-hash = "1.5"
|
||||||
raw-window-handle = "0.3"
|
raw-window-handle = "0.3"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
use stretch::{geometry, result};
|
use crate::{layout, renderer, Color, Event, Hasher, Layout, Point, Widget};
|
||||||
|
|
||||||
use crate::{renderer, Color, Event, Hasher, Layout, Node, Point, Widget};
|
|
||||||
|
|
||||||
/// A generic [`Widget`].
|
/// A generic [`Widget`].
|
||||||
///
|
///
|
||||||
|
|
@ -41,14 +39,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node(&self, renderer: &Renderer) -> Node {
|
pub fn layout(
|
||||||
self.widget.node(renderer)
|
&self,
|
||||||
|
renderer: &Renderer,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> Layout {
|
||||||
|
self.widget.layout(renderer, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(
|
pub fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
self.widget.draw(renderer, layout, cursor_position)
|
self.widget.draw(renderer, layout, cursor_position)
|
||||||
|
|
@ -247,12 +249,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compute_layout(&self, renderer: &Renderer) -> result::Layout {
|
|
||||||
let node = self.widget.node(renderer);
|
|
||||||
|
|
||||||
node.0.compute_layout(geometry::Size::undefined()).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn hash_layout(&self, state: &mut Hasher) {
|
pub(crate) fn hash_layout(&self, state: &mut Hasher) {
|
||||||
self.widget.hash_layout(state);
|
self.widget.hash_layout(state);
|
||||||
}
|
}
|
||||||
|
|
@ -289,14 +285,14 @@ where
|
||||||
A: Clone,
|
A: Clone,
|
||||||
Renderer: crate::Renderer,
|
Renderer: crate::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
self.widget.node(renderer)
|
self.widget.layout(renderer, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<B>,
|
messages: &mut Vec<B>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
|
@ -320,7 +316,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
self.widget.draw(renderer, layout, cursor_position)
|
self.widget.draw(renderer, layout, cursor_position)
|
||||||
|
|
@ -361,14 +357,14 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: crate::Renderer + renderer::Debugger,
|
Renderer: crate::Renderer + renderer::Debugger,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
self.element.widget.node(renderer)
|
self.element.widget.layout(renderer, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
|
@ -385,7 +381,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.explain(
|
renderer.explain(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
use stretch::result;
|
use crate::Rectangle;
|
||||||
|
|
||||||
use crate::{Point, Rectangle, Vector};
|
mod limits;
|
||||||
|
|
||||||
|
pub use limits::Limits;
|
||||||
|
|
||||||
/// The computed bounds of a [`Node`] and its children.
|
/// The computed bounds of a [`Node`] and its children.
|
||||||
///
|
///
|
||||||
|
|
@ -12,25 +14,25 @@ use crate::{Point, Rectangle, Vector};
|
||||||
/// [`Widget::on_event`]: widget/trait.Widget.html#method.on_event
|
/// [`Widget::on_event`]: widget/trait.Widget.html#method.on_event
|
||||||
/// [`Widget::draw`]: widget/trait.Widget.html#tymethod.draw
|
/// [`Widget::draw`]: widget/trait.Widget.html#tymethod.draw
|
||||||
/// [`Widget::node`]: widget/trait.Widget.html#tymethod.node
|
/// [`Widget::node`]: widget/trait.Widget.html#tymethod.node
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Layout<'a> {
|
pub struct Layout {
|
||||||
layout: &'a result::Layout,
|
bounds: Rectangle,
|
||||||
position: Point,
|
children: Vec<Layout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Layout<'a> {
|
impl Layout {
|
||||||
pub(crate) fn new(layout: &'a result::Layout) -> Self {
|
pub fn new(bounds: Rectangle) -> Self {
|
||||||
Self::with_parent_position(layout, Point::new(0.0, 0.0))
|
Layout {
|
||||||
|
bounds,
|
||||||
|
children: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_parent_position(
|
pub fn push(&mut self, mut child: Layout) {
|
||||||
layout: &'a result::Layout,
|
child.bounds.x += self.bounds.x;
|
||||||
parent_position: Point,
|
child.bounds.y += self.bounds.y;
|
||||||
) -> Self {
|
|
||||||
let position =
|
|
||||||
parent_position + Vector::new(layout.location.x, layout.location.y);
|
|
||||||
|
|
||||||
Layout { layout, position }
|
self.children.push(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the bounds of the [`Layout`].
|
/// Gets the bounds of the [`Layout`].
|
||||||
|
|
@ -42,21 +44,14 @@ impl<'a> Layout<'a> {
|
||||||
/// [`Rectangle`]: struct.Rectangle.html
|
/// [`Rectangle`]: struct.Rectangle.html
|
||||||
/// [`Node`]: struct.Node.html
|
/// [`Node`]: struct.Node.html
|
||||||
pub fn bounds(&self) -> Rectangle {
|
pub fn bounds(&self) -> Rectangle {
|
||||||
Rectangle {
|
self.bounds
|
||||||
x: self.position.x,
|
|
||||||
y: self.position.y,
|
|
||||||
width: self.layout.size.width,
|
|
||||||
height: self.layout.size.height,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the [`Layout`] of the children of a [`Node`].
|
/// Returns an iterator over the [`Layout`] of the children of a [`Node`].
|
||||||
///
|
///
|
||||||
/// [`Layout`]: struct.Layout.html
|
/// [`Layout`]: struct.Layout.html
|
||||||
/// [`Node`]: struct.Node.html
|
/// [`Node`]: struct.Node.html
|
||||||
pub fn children(&'a self) -> impl Iterator<Item = Layout<'a>> {
|
pub fn children(&self) -> impl Iterator<Item = &Layout> {
|
||||||
self.layout.children.iter().map(move |layout| {
|
self.children.iter()
|
||||||
Layout::with_parent_position(layout, self.position)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
native/src/layout/limits.rs
Normal file
6
native/src/layout/limits.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Limits {}
|
||||||
|
|
||||||
|
impl Limits {
|
||||||
|
pub const NONE: Limits = Limits {};
|
||||||
|
}
|
||||||
|
|
@ -199,32 +199,25 @@
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
#![deny(rust_2018_idioms)]
|
#![deny(rust_2018_idioms)]
|
||||||
pub mod input;
|
pub mod input;
|
||||||
|
pub mod layout;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
pub mod widget;
|
pub mod widget;
|
||||||
|
|
||||||
mod element;
|
mod element;
|
||||||
mod event;
|
mod event;
|
||||||
mod hasher;
|
mod hasher;
|
||||||
mod layout;
|
|
||||||
mod mouse_cursor;
|
mod mouse_cursor;
|
||||||
mod node;
|
|
||||||
mod style;
|
|
||||||
mod user_interface;
|
mod user_interface;
|
||||||
|
|
||||||
pub use iced_core::{
|
pub use iced_core::{
|
||||||
Align, Background, Color, Justify, Length, Point, Rectangle, Vector,
|
Align, Background, Color, Justify, Length, Point, Rectangle, Vector,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc(no_inline)]
|
|
||||||
pub use stretch::{geometry::Size, number::Number};
|
|
||||||
|
|
||||||
pub use element::Element;
|
pub use element::Element;
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use hasher::Hasher;
|
pub use hasher::Hasher;
|
||||||
pub use layout::Layout;
|
pub use layout::Layout;
|
||||||
pub use mouse_cursor::MouseCursor;
|
pub use mouse_cursor::MouseCursor;
|
||||||
pub use node::Node;
|
|
||||||
pub use renderer::Renderer;
|
pub use renderer::Renderer;
|
||||||
pub use style::Style;
|
|
||||||
pub use user_interface::{Cache, UserInterface};
|
pub use user_interface::{Cache, UserInterface};
|
||||||
pub use widget::*;
|
pub use widget::*;
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
use stretch::node;
|
|
||||||
|
|
||||||
use crate::{Number, Size, Style};
|
|
||||||
|
|
||||||
/// The visual requirements of a [`Widget`] and its children.
|
|
||||||
///
|
|
||||||
/// When there have been changes and the [`Layout`] needs to be recomputed, the
|
|
||||||
/// runtime obtains a [`Node`] by calling [`Widget::node`].
|
|
||||||
///
|
|
||||||
/// [`Style`]: struct.Style.html
|
|
||||||
/// [`Widget`]: widget/trait.Widget.html
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
/// [`Widget::node`]: widget/trait.Widget.html#tymethod.node
|
|
||||||
/// [`Layout`]: struct.Layout.html
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Node(pub(crate) node::Node);
|
|
||||||
|
|
||||||
impl Node {
|
|
||||||
/// Creates a new [`Node`] with the given [`Style`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
/// [`Style`]: struct.Style.html
|
|
||||||
pub fn new(style: Style) -> Node {
|
|
||||||
Self::with_children(style, Vec::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new [`Node`] with the given [`Style`] and a measure function.
|
|
||||||
///
|
|
||||||
/// This type of node cannot have any children.
|
|
||||||
///
|
|
||||||
/// You should use this when your [`Widget`] can adapt its contents to the
|
|
||||||
/// size of its container. The measure function will receive the container
|
|
||||||
/// size as a parameter and must compute the size of the [`Node`] inside
|
|
||||||
/// the given bounds (if the `Number` for a dimension is `Undefined` it
|
|
||||||
/// means that it has no boundary).
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
/// [`Style`]: struct.Style.html
|
|
||||||
/// [`Widget`]: widget/trait.Widget.html
|
|
||||||
pub fn with_measure<F>(style: Style, measure: F) -> Node
|
|
||||||
where
|
|
||||||
F: 'static + Fn(Size<Number>) -> Size<f32>,
|
|
||||||
{
|
|
||||||
Node(node::Node::new_leaf(
|
|
||||||
style.0,
|
|
||||||
Box::new(move |size| Ok(measure(size))),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new [`Node`] with the given [`Style`] and children.
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
/// [`Style`]: struct.Style.html
|
|
||||||
pub fn with_children(style: Style, children: Vec<Node>) -> Node {
|
|
||||||
Node(node::Node::new(
|
|
||||||
style.0,
|
|
||||||
children.iter().map(|c| &c.0).collect(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -18,7 +18,7 @@ pub trait Debugger: super::Renderer {
|
||||||
fn explain<Message>(
|
fn explain<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
widget: &dyn Widget<Message, Self>,
|
widget: &dyn Widget<Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
color: Color,
|
color: Color,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
|
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
||||||
use crate::{Align, Justify, Length};
|
|
||||||
|
|
||||||
use stretch::style;
|
|
||||||
|
|
||||||
/// The appearance of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Style(pub(crate) style::Style);
|
|
||||||
|
|
||||||
impl Default for Style {
|
|
||||||
fn default() -> Style {
|
|
||||||
Style::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Style {
|
|
||||||
/// Creates a new [`Style`].
|
|
||||||
///
|
|
||||||
/// [`Style`]: struct.Style.html
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Style(style::Style {
|
|
||||||
align_items: style::AlignItems::FlexStart,
|
|
||||||
justify_content: style::JustifyContent::FlexStart,
|
|
||||||
..style::Style::default()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines the width of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
pub fn width(mut self, width: Length) -> Self {
|
|
||||||
self.0.size.width = into_dimension(width);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines the height of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
pub fn height(mut self, height: Length) -> Self {
|
|
||||||
self.0.size.height = into_dimension(height);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines the minimum width of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
pub fn min_width(mut self, min_width: Length) -> Self {
|
|
||||||
self.0.min_size.width = into_dimension(min_width);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines the maximum width of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
pub fn max_width(mut self, max_width: Length) -> Self {
|
|
||||||
self.0.max_size.width = into_dimension(max_width);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines the minimum height of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
pub fn min_height(mut self, min_height: Length) -> Self {
|
|
||||||
self.0.min_size.height = into_dimension(min_height);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines the maximum height of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
pub fn max_height(mut self, max_height: Length) -> Self {
|
|
||||||
self.0.max_size.height = into_dimension(max_height);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn align_items(mut self, align: Align) -> Self {
|
|
||||||
self.0.align_items = into_align_items(align);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn justify_content(mut self, justify: Justify) -> Self {
|
|
||||||
self.0.justify_content = into_justify_content(justify);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the alignment of a [`Node`].
|
|
||||||
///
|
|
||||||
/// If the [`Node`] is inside a...
|
|
||||||
///
|
|
||||||
/// * [`Column`], this setting will affect its __horizontal__ alignment.
|
|
||||||
/// * [`Row`], this setting will affect its __vertical__ alignment.
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
/// [`Column`]: widget/struct.Column.html
|
|
||||||
/// [`Row`]: widget/struct.Row.html
|
|
||||||
pub fn align_self(mut self, align: Option<Align>) -> Self {
|
|
||||||
self.0.align_self = match align {
|
|
||||||
Some(align) => into_align_self(align),
|
|
||||||
None => stretch::style::AlignSelf::Auto,
|
|
||||||
};
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the padding of a [`Node`].
|
|
||||||
///
|
|
||||||
/// [`Node`]: struct.Node.html
|
|
||||||
pub fn padding(mut self, units: u16) -> Self {
|
|
||||||
self.0.padding = stretch::geometry::Rect {
|
|
||||||
start: style::Dimension::Points(units as f32),
|
|
||||||
end: style::Dimension::Points(units as f32),
|
|
||||||
top: style::Dimension::Points(units as f32),
|
|
||||||
bottom: style::Dimension::Points(units as f32),
|
|
||||||
};
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_dimension(length: Length) -> style::Dimension {
|
|
||||||
match length {
|
|
||||||
Length::Shrink => style::Dimension::Undefined,
|
|
||||||
Length::Fill => style::Dimension::Percent(1.0),
|
|
||||||
Length::Units(units) => style::Dimension::Points(units as f32),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_align_items(align: Align) -> style::AlignItems {
|
|
||||||
match align {
|
|
||||||
Align::Start => style::AlignItems::FlexStart,
|
|
||||||
Align::Center => style::AlignItems::Center,
|
|
||||||
Align::End => style::AlignItems::FlexEnd,
|
|
||||||
Align::Stretch => style::AlignItems::Stretch,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_align_self(align: Align) -> style::AlignSelf {
|
|
||||||
match align {
|
|
||||||
Align::Start => style::AlignSelf::FlexStart,
|
|
||||||
Align::Center => style::AlignSelf::Center,
|
|
||||||
Align::End => style::AlignSelf::FlexEnd,
|
|
||||||
Align::Stretch => style::AlignSelf::Stretch,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_justify_content(justify: Justify) -> style::JustifyContent {
|
|
||||||
match justify {
|
|
||||||
Justify::Start => style::JustifyContent::FlexStart,
|
|
||||||
Justify::Center => style::JustifyContent::Center,
|
|
||||||
Justify::End => style::JustifyContent::FlexEnd,
|
|
||||||
Justify::SpaceBetween => style::JustifyContent::SpaceBetween,
|
|
||||||
Justify::SpaceAround => style::JustifyContent::SpaceAround,
|
|
||||||
Justify::SpaceEvenly => style::JustifyContent::SpaceEvenly,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::{input::mouse, Element, Event, Layout, Point};
|
use crate::{input::mouse, layout, Element, Event, Layout, Point, Rectangle};
|
||||||
|
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use stretch::{geometry, result};
|
|
||||||
|
|
||||||
/// A set of interactive graphical elements with a specific [`Layout`].
|
/// A set of interactive graphical elements with a specific [`Layout`].
|
||||||
///
|
///
|
||||||
|
|
@ -15,7 +14,7 @@ use stretch::{geometry, result};
|
||||||
pub struct UserInterface<'a, Message, Renderer> {
|
pub struct UserInterface<'a, Message, Renderer> {
|
||||||
hash: u64,
|
hash: u64,
|
||||||
root: Element<'a, Message, Renderer>,
|
root: Element<'a, Message, Renderer>,
|
||||||
layout: result::Layout,
|
layout: Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +109,7 @@ where
|
||||||
let layout = if hash == cache.hash {
|
let layout = if hash == cache.hash {
|
||||||
cache.layout
|
cache.layout
|
||||||
} else {
|
} else {
|
||||||
root.compute_layout(renderer)
|
root.layout(renderer, &layout::Limits::NONE)
|
||||||
};
|
};
|
||||||
|
|
||||||
UserInterface {
|
UserInterface {
|
||||||
|
|
@ -210,7 +209,7 @@ where
|
||||||
|
|
||||||
self.root.widget.on_event(
|
self.root.widget.on_event(
|
||||||
event,
|
event,
|
||||||
Layout::new(&self.layout),
|
&self.layout,
|
||||||
self.cursor_position,
|
self.cursor_position,
|
||||||
&mut messages,
|
&mut messages,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -299,11 +298,9 @@ where
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn draw(&self, renderer: &mut Renderer) -> Renderer::Output {
|
pub fn draw(&self, renderer: &mut Renderer) -> Renderer::Output {
|
||||||
self.root.widget.draw(
|
self.root
|
||||||
renderer,
|
.widget
|
||||||
Layout::new(&self.layout),
|
.draw(renderer, &self.layout, self.cursor_position)
|
||||||
self.cursor_position,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the [`Cache`] of the [`UserInterface`], consuming it in the
|
/// Extract the [`Cache`] of the [`UserInterface`], consuming it in the
|
||||||
|
|
@ -326,7 +323,7 @@ where
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Cache {
|
pub struct Cache {
|
||||||
hash: u64,
|
hash: u64,
|
||||||
layout: result::Layout,
|
layout: Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -339,16 +336,14 @@ impl Cache {
|
||||||
/// [`Cache`]: struct.Cache.html
|
/// [`Cache`]: struct.Cache.html
|
||||||
/// [`UserInterface`]: struct.UserInterface.html
|
/// [`UserInterface`]: struct.UserInterface.html
|
||||||
pub fn new() -> Cache {
|
pub fn new() -> Cache {
|
||||||
use crate::{Node, Style};
|
|
||||||
|
|
||||||
let empty_node = Node::new(Style::default());
|
|
||||||
|
|
||||||
Cache {
|
Cache {
|
||||||
hash: 0,
|
hash: 0,
|
||||||
layout: empty_node
|
layout: Layout::new(Rectangle {
|
||||||
.0
|
x: 0.0,
|
||||||
.compute_layout(geometry::Size::undefined())
|
y: 0.0,
|
||||||
.unwrap(),
|
width: 0.0,
|
||||||
|
height: 0.0,
|
||||||
|
}),
|
||||||
cursor_position: Point::new(-1.0, -1.0),
|
cursor_position: Point::new(-1.0, -1.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ pub use text::Text;
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use text_input::TextInput;
|
pub use text_input::TextInput;
|
||||||
|
|
||||||
use crate::{Event, Hasher, Layout, Node, Point};
|
use crate::{layout, Event, Hasher, Layout, Point};
|
||||||
|
|
||||||
/// A component that displays information and allows interaction.
|
/// A component that displays information and allows interaction.
|
||||||
///
|
///
|
||||||
|
|
@ -73,7 +73,7 @@ where
|
||||||
/// [`Node`]: ../struct.Node.html
|
/// [`Node`]: ../struct.Node.html
|
||||||
/// [`Widget`]: trait.Widget.html
|
/// [`Widget`]: trait.Widget.html
|
||||||
/// [`Layout`]: ../struct.Layout.html
|
/// [`Layout`]: ../struct.Layout.html
|
||||||
fn node(&self, renderer: &Renderer) -> Node;
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout;
|
||||||
|
|
||||||
/// Draws the [`Widget`] using the associated `Renderer`.
|
/// Draws the [`Widget`] using the associated `Renderer`.
|
||||||
///
|
///
|
||||||
|
|
@ -81,7 +81,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output;
|
) -> Renderer::Output;
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ where
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_event: Event,
|
_event: Event,
|
||||||
_layout: Layout<'_>,
|
_layout: &Layout,
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
_messages: &mut Vec<Message>,
|
_messages: &mut Vec<Message>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
//! [`Class`]: enum.Class.html
|
//! [`Class`]: enum.Class.html
|
||||||
|
|
||||||
use crate::input::{mouse, ButtonState};
|
use crate::input::{mouse, ButtonState};
|
||||||
use crate::{Element, Event, Hasher, Layout, Node, Point, Widget};
|
use crate::{layout, Element, Event, Hasher, Layout, Point, Widget};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
pub use iced_core::button::State;
|
pub use iced_core::button::State;
|
||||||
|
|
@ -21,14 +21,14 @@ where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
Message: Clone + std::fmt::Debug,
|
Message: Clone + std::fmt::Debug,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
renderer.node(&self)
|
renderer.layout(&self, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
|
|
@ -66,7 +66,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout, cursor_position)
|
renderer.draw(&self, layout, cursor_position)
|
||||||
|
|
@ -91,7 +91,11 @@ pub trait Renderer: crate::Renderer + Sized {
|
||||||
///
|
///
|
||||||
/// [`Node`]: ../../struct.Node.html
|
/// [`Node`]: ../../struct.Node.html
|
||||||
/// [`Button`]: struct.Button.html
|
/// [`Button`]: struct.Button.html
|
||||||
fn node<Message>(&self, button: &Button<'_, Message, Self>) -> Node;
|
fn layout<Message>(
|
||||||
|
&self,
|
||||||
|
button: &Button<'_, Message, Self>,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> Layout;
|
||||||
|
|
||||||
/// Draws a [`Button`].
|
/// Draws a [`Button`].
|
||||||
///
|
///
|
||||||
|
|
@ -99,7 +103,7 @@ pub trait Renderer: crate::Renderer + Sized {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
button: &Button<'_, Message, Self>,
|
button: &Button<'_, Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use crate::input::{mouse, ButtonState};
|
use crate::input::{mouse, ButtonState};
|
||||||
use crate::{Element, Event, Hasher, Layout, Node, Point, Widget};
|
use crate::{layout, Element, Event, Hasher, Layout, Point, Widget};
|
||||||
|
|
||||||
pub use iced_core::Checkbox;
|
pub use iced_core::Checkbox;
|
||||||
|
|
||||||
|
|
@ -10,14 +10,14 @@ impl<Message, Renderer> Widget<Message, Renderer> for Checkbox<Message>
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
renderer.node(&self)
|
renderer.layout(&self, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
|
|
@ -40,7 +40,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout, cursor_position)
|
renderer.draw(&self, layout, cursor_position)
|
||||||
|
|
@ -63,7 +63,11 @@ pub trait Renderer: crate::Renderer {
|
||||||
///
|
///
|
||||||
/// [`Node`]: ../../struct.Node.html
|
/// [`Node`]: ../../struct.Node.html
|
||||||
/// [`Checkbox`]: struct.Checkbox.html
|
/// [`Checkbox`]: struct.Checkbox.html
|
||||||
fn node<Message>(&self, checkbox: &Checkbox<Message>) -> Node;
|
fn layout<Message>(
|
||||||
|
&self,
|
||||||
|
checkbox: &Checkbox<Message>,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> Layout;
|
||||||
|
|
||||||
/// Draws a [`Checkbox`].
|
/// Draws a [`Checkbox`].
|
||||||
///
|
///
|
||||||
|
|
@ -77,7 +81,7 @@ pub trait Renderer: crate::Renderer {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
checkbox: &Checkbox<Message>,
|
checkbox: &Checkbox<Message>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use crate::{Element, Event, Hasher, Layout, Node, Point, Style, Widget};
|
use crate::{layout, Element, Event, Hasher, Layout, Point, Rectangle, Widget};
|
||||||
|
|
||||||
/// A container that distributes its contents vertically.
|
/// A container that distributes its contents vertically.
|
||||||
pub type Column<'a, Message, Renderer> =
|
pub type Column<'a, Message, Renderer> =
|
||||||
|
|
@ -11,48 +11,20 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
let mut children: Vec<Node> = self
|
// TODO
|
||||||
.children
|
Layout::new(Rectangle {
|
||||||
.iter()
|
x: 0.0,
|
||||||
.map(|child| {
|
y: 0.0,
|
||||||
let mut node = child.widget.node(renderer);
|
width: 0.0,
|
||||||
|
height: 0.0,
|
||||||
let mut style = node.0.style();
|
})
|
||||||
style.margin.bottom =
|
|
||||||
stretch::style::Dimension::Points(f32::from(self.spacing));
|
|
||||||
|
|
||||||
node.0.set_style(style);
|
|
||||||
node
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if let Some(node) = children.last_mut() {
|
|
||||||
let mut style = node.0.style();
|
|
||||||
style.margin.bottom = stretch::style::Dimension::Undefined;
|
|
||||||
|
|
||||||
node.0.set_style(style);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut style = Style::default()
|
|
||||||
.width(self.width)
|
|
||||||
.height(self.height)
|
|
||||||
.max_width(self.max_width)
|
|
||||||
.max_height(self.max_height)
|
|
||||||
.padding(self.padding)
|
|
||||||
.align_self(self.align_self)
|
|
||||||
.align_items(self.align_items)
|
|
||||||
.justify_content(self.justify_content);
|
|
||||||
|
|
||||||
style.0.flex_direction = stretch::style::FlexDirection::Column;
|
|
||||||
|
|
||||||
Node::with_children(style, children)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
|
@ -73,7 +45,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout, cursor_position)
|
renderer.draw(&self, layout, cursor_position)
|
||||||
|
|
@ -100,7 +72,7 @@ pub trait Renderer: crate::Renderer + Sized {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
row: &Column<'_, Message, Self>,
|
row: &Column<'_, Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//! Display images in your user interface.
|
//! Display images in your user interface.
|
||||||
|
|
||||||
use crate::{Element, Hasher, Layout, Node, Point, Widget};
|
use crate::{layout, Element, Hasher, Layout, Point, Widget};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
|
@ -10,14 +10,14 @@ impl<Message, Renderer> Widget<Message, Renderer> for Image
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
renderer.node(&self)
|
renderer.layout(&self, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout)
|
renderer.draw(&self, layout)
|
||||||
|
|
@ -44,12 +44,12 @@ pub trait Renderer: crate::Renderer {
|
||||||
///
|
///
|
||||||
/// [`Node`]: ../../struct.Node.html
|
/// [`Node`]: ../../struct.Node.html
|
||||||
/// [`Image`]: struct.Image.html
|
/// [`Image`]: struct.Image.html
|
||||||
fn node(&self, image: &Image) -> Node;
|
fn layout(&self, image: &Image, limits: &layout::Limits) -> Layout;
|
||||||
|
|
||||||
/// Draws an [`Image`].
|
/// Draws an [`Image`].
|
||||||
///
|
///
|
||||||
/// [`Image`]: struct.Image.html
|
/// [`Image`]: struct.Image.html
|
||||||
fn draw(&mut self, image: &Image, layout: Layout<'_>) -> Self::Output;
|
fn draw(&mut self, image: &Image, layout: &Layout) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> From<Image> for Element<'a, Message, Renderer>
|
impl<'a, Message, Renderer> From<Image> for Element<'a, Message, Renderer>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//! Create choices using radio buttons.
|
//! Create choices using radio buttons.
|
||||||
use crate::input::{mouse, ButtonState};
|
use crate::input::{mouse, ButtonState};
|
||||||
use crate::{Element, Event, Hasher, Layout, Node, Point, Widget};
|
use crate::{layout, Element, Event, Hasher, Layout, Point, Widget};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
|
@ -11,14 +11,14 @@ where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
Message: Clone + std::fmt::Debug,
|
Message: Clone + std::fmt::Debug,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
renderer.node(&self)
|
renderer.layout(&self, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
|
|
@ -39,7 +39,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout, cursor_position)
|
renderer.draw(&self, layout, cursor_position)
|
||||||
|
|
@ -62,7 +62,11 @@ pub trait Renderer: crate::Renderer {
|
||||||
///
|
///
|
||||||
/// [`Node`]: ../../struct.Node.html
|
/// [`Node`]: ../../struct.Node.html
|
||||||
/// [`Radio`]: struct.Radio.html
|
/// [`Radio`]: struct.Radio.html
|
||||||
fn node<Message>(&self, radio: &Radio<Message>) -> Node;
|
fn layout<Message>(
|
||||||
|
&self,
|
||||||
|
radio: &Radio<Message>,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> Layout;
|
||||||
|
|
||||||
/// Draws a [`Radio`] button.
|
/// Draws a [`Radio`] button.
|
||||||
///
|
///
|
||||||
|
|
@ -76,7 +80,7 @@ pub trait Renderer: crate::Renderer {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
radio: &Radio<Message>,
|
radio: &Radio<Message>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use crate::{Element, Event, Hasher, Layout, Node, Point, Style, Widget};
|
use crate::{layout, Element, Event, Hasher, Layout, Point, Rectangle, Widget};
|
||||||
|
|
||||||
/// A container that distributes its contents horizontally.
|
/// A container that distributes its contents horizontally.
|
||||||
pub type Row<'a, Message, Renderer> =
|
pub type Row<'a, Message, Renderer> =
|
||||||
|
|
@ -11,48 +11,20 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
let mut children: Vec<Node> = self
|
// TODO
|
||||||
.children
|
Layout::new(Rectangle {
|
||||||
.iter()
|
x: 0.0,
|
||||||
.map(|child| {
|
y: 0.0,
|
||||||
let mut node = child.widget.node(renderer);
|
width: 0.0,
|
||||||
|
height: 0.0,
|
||||||
let mut style = node.0.style();
|
})
|
||||||
style.margin.end =
|
|
||||||
stretch::style::Dimension::Points(f32::from(self.spacing));
|
|
||||||
|
|
||||||
node.0.set_style(style);
|
|
||||||
node
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if let Some(node) = children.last_mut() {
|
|
||||||
let mut style = node.0.style();
|
|
||||||
style.margin.end = stretch::style::Dimension::Undefined;
|
|
||||||
|
|
||||||
node.0.set_style(style);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut style = Style::default()
|
|
||||||
.width(self.width)
|
|
||||||
.height(self.height)
|
|
||||||
.max_width(self.max_width)
|
|
||||||
.max_height(self.max_height)
|
|
||||||
.padding(self.padding)
|
|
||||||
.align_self(self.align_self)
|
|
||||||
.align_items(self.align_items)
|
|
||||||
.justify_content(self.justify_content);
|
|
||||||
|
|
||||||
style.0.flex_direction = stretch::style::FlexDirection::Row;
|
|
||||||
|
|
||||||
Node::with_children(style, children)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
|
@ -73,7 +45,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout, cursor_position)
|
renderer.draw(&self, layout, cursor_position)
|
||||||
|
|
@ -101,7 +73,7 @@ pub trait Renderer: crate::Renderer + Sized {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
row: &Row<'_, Message, Self>,
|
row: &Row<'_, Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
column,
|
column,
|
||||||
input::{mouse, ButtonState},
|
input::{mouse, ButtonState},
|
||||||
Element, Event, Hasher, Layout, Node, Point, Rectangle, Style, Widget,
|
layout, Element, Event, Hasher, Layout, Point, Rectangle, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use iced_core::scrollable::State;
|
pub use iced_core::scrollable::State;
|
||||||
|
|
@ -19,32 +19,15 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer + column::Renderer,
|
Renderer: self::Renderer + column::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
let mut content = self.content.node(renderer);
|
// TODO
|
||||||
|
self.content.layout(renderer, limits)
|
||||||
{
|
|
||||||
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)
|
|
||||||
.max_height(self.max_height)
|
|
||||||
.align_self(self.align_self);
|
|
||||||
|
|
||||||
style.0.flex_direction = stretch::style::FlexDirection::Column;
|
|
||||||
|
|
||||||
Node::with_children(style, vec![content])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
|
|
@ -147,7 +130,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
@ -185,7 +168,7 @@ pub trait Renderer: crate::Renderer + Sized {
|
||||||
&mut self,
|
&mut self,
|
||||||
scrollable: &Scrollable<'_, Message, Self>,
|
scrollable: &Scrollable<'_, Message, Self>,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
content_layout: Layout<'_>,
|
content_layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use crate::input::{mouse, ButtonState};
|
use crate::input::{mouse, ButtonState};
|
||||||
use crate::{Element, Event, Hasher, Layout, Node, Point, Widget};
|
use crate::{layout, Element, Event, Hasher, Layout, Point, Widget};
|
||||||
|
|
||||||
pub use iced_core::slider::*;
|
pub use iced_core::slider::*;
|
||||||
|
|
||||||
|
|
@ -15,14 +15,14 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> for Slider<'a, Message>
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
renderer.node(&self)
|
renderer.layout(&self, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
|
|
@ -70,7 +70,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout, cursor_position)
|
renderer.draw(&self, layout, cursor_position)
|
||||||
|
|
@ -93,7 +93,11 @@ pub trait Renderer: crate::Renderer {
|
||||||
///
|
///
|
||||||
/// [`Node`]: ../../struct.Node.html
|
/// [`Node`]: ../../struct.Node.html
|
||||||
/// [`Radio`]: struct.Radio.html
|
/// [`Radio`]: struct.Radio.html
|
||||||
fn node<Message>(&self, slider: &Slider<'_, Message>) -> Node;
|
fn layout<Message>(
|
||||||
|
&self,
|
||||||
|
slider: &Slider<'_, Message>,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> Layout;
|
||||||
|
|
||||||
/// Draws a [`Slider`].
|
/// Draws a [`Slider`].
|
||||||
///
|
///
|
||||||
|
|
@ -110,7 +114,7 @@ pub trait Renderer: crate::Renderer {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
slider: &Slider<'_, Message>,
|
slider: &Slider<'_, Message>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//! Write some text for your users to read.
|
//! Write some text for your users to read.
|
||||||
use crate::{Element, Hasher, Layout, Node, Point, Widget};
|
use crate::{layout, Element, Hasher, Layout, Point, Widget};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
|
@ -9,14 +9,14 @@ impl<Message, Renderer> Widget<Message, Renderer> for Text
|
||||||
where
|
where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
renderer.node(&self)
|
renderer.layout(&self, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
renderer.draw(&self, layout)
|
renderer.draw(&self, layout)
|
||||||
|
|
@ -49,7 +49,7 @@ pub trait Renderer: crate::Renderer {
|
||||||
/// [`Style`]: ../../struct.Style.html
|
/// [`Style`]: ../../struct.Style.html
|
||||||
/// [`Text`]: struct.Text.html
|
/// [`Text`]: struct.Text.html
|
||||||
/// [`Node::with_measure`]: ../../struct.Node.html#method.with_measure
|
/// [`Node::with_measure`]: ../../struct.Node.html#method.with_measure
|
||||||
fn node(&self, text: &Text) -> Node;
|
fn layout(&self, text: &Text, limits: &layout::Limits) -> Layout;
|
||||||
|
|
||||||
/// Draws a [`Text`] fragment.
|
/// Draws a [`Text`] fragment.
|
||||||
///
|
///
|
||||||
|
|
@ -64,7 +64,7 @@ pub trait Renderer: crate::Renderer {
|
||||||
/// [`Text`]: struct.Text.html
|
/// [`Text`]: struct.Text.html
|
||||||
/// [`HorizontalAlignment`]: enum.HorizontalAlignment.html
|
/// [`HorizontalAlignment`]: enum.HorizontalAlignment.html
|
||||||
/// [`VerticalAlignment`]: enum.VerticalAlignment.html
|
/// [`VerticalAlignment`]: enum.VerticalAlignment.html
|
||||||
fn draw(&mut self, text: &Text, layout: Layout<'_>) -> Self::Output;
|
fn draw(&mut self, text: &Text, layout: &Layout) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> From<Text> for Element<'a, Message, Renderer>
|
impl<'a, Message, Renderer> From<Text> for Element<'a, Message, Renderer>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
input::{keyboard, mouse, ButtonState},
|
input::{keyboard, mouse, ButtonState},
|
||||||
Element, Event, Hasher, Layout, Length, Node, Point, Rectangle, Style,
|
layout, Element, Event, Hasher, Layout, Point, Rectangle, Widget,
|
||||||
Widget,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use iced_core::{text_input::State, TextInput};
|
pub use iced_core::{text_input::State, TextInput};
|
||||||
|
|
@ -11,25 +10,20 @@ where
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
Message: Clone + std::fmt::Debug,
|
Message: Clone + std::fmt::Debug,
|
||||||
{
|
{
|
||||||
fn node(&self, renderer: &Renderer) -> Node {
|
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> Layout {
|
||||||
let text_bounds =
|
// TODO
|
||||||
Node::new(Style::default().width(Length::Fill).height(
|
Layout::new(Rectangle {
|
||||||
Length::Units(self.size.unwrap_or(renderer.default_size())),
|
x: 0.0,
|
||||||
));
|
y: 0.0,
|
||||||
|
width: 0.0,
|
||||||
Node::with_children(
|
height: 0.0,
|
||||||
Style::default()
|
})
|
||||||
.width(self.width)
|
|
||||||
.max_width(self.width)
|
|
||||||
.padding(self.padding),
|
|
||||||
vec![text_bounds],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
|
|
@ -101,7 +95,7 @@ where
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ impl Debugger for Renderer {
|
||||||
fn explain<Message>(
|
fn explain<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
widget: &dyn Widget<Message, Self>,
|
widget: &dyn Widget<Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
color: Color,
|
color: Color,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
|
|
@ -438,7 +438,7 @@ impl Debugger for Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn explain_layout(
|
fn explain_layout(
|
||||||
layout: Layout,
|
layout: &Layout,
|
||||||
color: Color,
|
color: Color,
|
||||||
primitives: &mut Vec<Primitive>,
|
primitives: &mut Vec<Primitive>,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,27 @@
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
button, Align, Background, Button, Layout, Length, MouseCursor,
|
button, layout, Background, Button, Layout, MouseCursor, Point, Rectangle,
|
||||||
Node, Point, Rectangle, Style,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl button::Renderer for Renderer {
|
impl button::Renderer for Renderer {
|
||||||
fn node<Message>(&self, button: &Button<Message, Self>) -> Node {
|
fn layout<Message>(
|
||||||
let style = Style::default()
|
&self,
|
||||||
.width(button.width)
|
button: &Button<Message, Self>,
|
||||||
.padding(button.padding)
|
limits: &layout::Limits,
|
||||||
.min_width(Length::Units(100))
|
) -> Layout {
|
||||||
.align_self(button.align_self)
|
// TODO
|
||||||
.align_items(Align::Stretch);
|
Layout::new(Rectangle {
|
||||||
|
x: 0.0,
|
||||||
Node::with_children(style, vec![button.content.node(self)])
|
y: 0.0,
|
||||||
|
width: 0.0,
|
||||||
|
height: 0.0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
button: &Button<Message, Self>,
|
button: &Button<Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,30 @@
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
checkbox, text, text::HorizontalAlignment, text::VerticalAlignment, Align,
|
checkbox, layout, text, text::HorizontalAlignment, text::VerticalAlignment,
|
||||||
Background, Checkbox, Column, Layout, Length, MouseCursor, Node,
|
Background, Checkbox, Layout, MouseCursor, Point, Rectangle, Text,
|
||||||
Point, Rectangle, Row, Text, Widget,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SIZE: f32 = 28.0;
|
const SIZE: f32 = 28.0;
|
||||||
|
|
||||||
impl checkbox::Renderer for Renderer {
|
impl checkbox::Renderer for Renderer {
|
||||||
fn node<Message>(&self, checkbox: &Checkbox<Message>) -> Node {
|
fn layout<Message>(
|
||||||
Row::<(), Self>::new()
|
&self,
|
||||||
.width(Length::Fill)
|
checkbox: &Checkbox<Message>,
|
||||||
.spacing(15)
|
limits: &layout::Limits,
|
||||||
.align_items(Align::Center)
|
) -> Layout {
|
||||||
.push(
|
// TODO
|
||||||
Column::new()
|
Layout::new(Rectangle {
|
||||||
.width(Length::Units(SIZE as u16))
|
x: 0.0,
|
||||||
.height(Length::Units(SIZE as u16)),
|
y: 0.0,
|
||||||
)
|
width: 0.0,
|
||||||
.push(Text::new(&checkbox.label))
|
height: 0.0,
|
||||||
.node(self)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
checkbox: &Checkbox<Message>,
|
checkbox: &Checkbox<Message>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ impl column::Renderer for Renderer {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
column: &Column<'_, Message, Self>,
|
column: &Column<'_, Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let mut mouse_cursor = MouseCursor::OutOfBounds;
|
let mut mouse_cursor = MouseCursor::OutOfBounds;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,18 @@
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{image, Image, Layout, Length, MouseCursor, Node, Style};
|
use iced_native::{image, layout, Image, Layout, MouseCursor, Rectangle};
|
||||||
|
|
||||||
impl image::Renderer for Renderer {
|
impl image::Renderer for Renderer {
|
||||||
fn node(&self, image: &Image) -> Node {
|
fn layout(&self, image: &Image, limits: &layout::Limits) -> Layout {
|
||||||
let (width, height) = self.image_pipeline.dimensions(&image.path);
|
// TODO
|
||||||
|
Layout::new(Rectangle {
|
||||||
let aspect_ratio = width as f32 / height as f32;
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
let mut style = Style::default().align_self(image.align_self);
|
width: 0.0,
|
||||||
|
height: 0.0,
|
||||||
// TODO: Deal with additional cases
|
})
|
||||||
style = match (image.width, image.height) {
|
|
||||||
(Length::Units(width), _) => style.width(image.width).height(
|
|
||||||
Length::Units((width as f32 / aspect_ratio).round() as u16),
|
|
||||||
),
|
|
||||||
(_, _) => style
|
|
||||||
.width(Length::Units(width as u16))
|
|
||||||
.height(Length::Units(height as u16)),
|
|
||||||
};
|
|
||||||
|
|
||||||
Node::new(style)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self, image: &Image, layout: Layout<'_>) -> Self::Output {
|
fn draw(&mut self, image: &Image, layout: &Layout) -> Self::Output {
|
||||||
(
|
(
|
||||||
Primitive::Image {
|
Primitive::Image {
|
||||||
path: image.path.clone(),
|
path: image.path.clone(),
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,31 @@
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
radio, text, Align, Background, Column, Layout, Length, MouseCursor,
|
layout, radio, text, Background, Layout, MouseCursor, Point, Radio,
|
||||||
Node, Point, Radio, Rectangle, Row, Text, Widget,
|
Rectangle, Text,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SIZE: f32 = 28.0;
|
const SIZE: f32 = 28.0;
|
||||||
const DOT_SIZE: f32 = SIZE / 2.0;
|
const DOT_SIZE: f32 = SIZE / 2.0;
|
||||||
|
|
||||||
impl radio::Renderer for Renderer {
|
impl radio::Renderer for Renderer {
|
||||||
fn node<Message>(&self, radio: &Radio<Message>) -> Node {
|
fn layout<Message>(
|
||||||
Row::<(), Self>::new()
|
&self,
|
||||||
.spacing(15)
|
radio: &Radio<Message>,
|
||||||
.align_items(Align::Center)
|
limits: &layout::Limits,
|
||||||
.push(
|
) -> Layout {
|
||||||
Column::new()
|
// TODO
|
||||||
.width(Length::Units(SIZE as u16))
|
Layout::new(Rectangle {
|
||||||
.height(Length::Units(SIZE as u16)),
|
x: 0.0,
|
||||||
)
|
y: 0.0,
|
||||||
.push(Text::new(&radio.label))
|
width: 0.0,
|
||||||
.node(self)
|
height: 0.0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
radio: &Radio<Message>,
|
radio: &Radio<Message>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ impl row::Renderer for Renderer {
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
row: &Row<'_, Message, Self>,
|
row: &Row<'_, Message, Self>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let mut mouse_cursor = MouseCursor::OutOfBounds;
|
let mut mouse_cursor = MouseCursor::OutOfBounds;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
scrollable, Background, Layout, MouseCursor, Point, Rectangle,
|
scrollable, Background, Layout, MouseCursor, Point, Rectangle, Scrollable,
|
||||||
Scrollable, Vector, Widget,
|
Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SCROLLBAR_WIDTH: u16 = 10;
|
const SCROLLBAR_WIDTH: u16 = 10;
|
||||||
|
|
@ -32,7 +32,7 @@ impl scrollable::Renderer for Renderer {
|
||||||
&mut self,
|
&mut self,
|
||||||
scrollable: &Scrollable<'_, Message, Self>,
|
scrollable: &Scrollable<'_, Message, Self>,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
content: Layout<'_>,
|
content: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let is_mouse_over = bounds.contains(cursor_position);
|
let is_mouse_over = bounds.contains(cursor_position);
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,31 @@
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
slider, Background, Color, Layout, Length, MouseCursor, Node, Point,
|
layout, slider, Background, Color, Layout, MouseCursor, Point, Rectangle,
|
||||||
Rectangle, Slider, Style,
|
Slider,
|
||||||
};
|
};
|
||||||
|
|
||||||
const HANDLE_WIDTH: f32 = 8.0;
|
const HANDLE_WIDTH: f32 = 8.0;
|
||||||
const HANDLE_HEIGHT: f32 = 22.0;
|
const HANDLE_HEIGHT: f32 = 22.0;
|
||||||
|
|
||||||
impl slider::Renderer for Renderer {
|
impl slider::Renderer for Renderer {
|
||||||
fn node<Message>(&self, slider: &Slider<Message>) -> Node {
|
fn layout<Message>(
|
||||||
let style = Style::default()
|
&self,
|
||||||
.width(slider.width)
|
slider: &Slider<Message>,
|
||||||
.height(Length::Units(HANDLE_HEIGHT as u16))
|
limits: &layout::Limits,
|
||||||
.min_width(Length::Units(100));
|
) -> Layout {
|
||||||
|
// TODO
|
||||||
Node::new(style)
|
Layout::new(Rectangle {
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
width: 0.0,
|
||||||
|
height: 0.0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<Message>(
|
fn draw<Message>(
|
||||||
&mut self,
|
&mut self,
|
||||||
slider: &Slider<Message>,
|
slider: &Slider<Message>,
|
||||||
layout: Layout<'_>,
|
layout: &Layout,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,25 @@
|
||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{text, Color, Layout, MouseCursor, Node, Style, Text};
|
use iced_native::{layout, text, Color, Layout, MouseCursor, Rectangle, Text};
|
||||||
|
|
||||||
use wgpu_glyph::{GlyphCruncher, Section};
|
//use wgpu_glyph::{GlyphCruncher, Section};
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::f32;
|
use std::f32;
|
||||||
|
|
||||||
// TODO: Obtain from renderer configuration
|
// TODO: Obtain from renderer configuration
|
||||||
const DEFAULT_TEXT_SIZE: f32 = 20.0;
|
const DEFAULT_TEXT_SIZE: f32 = 20.0;
|
||||||
|
|
||||||
impl text::Renderer for Renderer {
|
impl text::Renderer for Renderer {
|
||||||
fn node(&self, text: &Text) -> Node {
|
fn layout(&self, text: &Text, limits: &layout::Limits) -> Layout {
|
||||||
let glyph_brush = self.glyph_brush.clone();
|
// TODO
|
||||||
let content = text.content.clone();
|
Layout::new(Rectangle {
|
||||||
|
x: 0.0,
|
||||||
// TODO: Investigate why stretch tries to measure this MANY times
|
y: 0.0,
|
||||||
// with every ancestor's bounds.
|
width: 0.0,
|
||||||
// Bug? Using the library wrong? I should probably open an issue on
|
height: 0.0,
|
||||||
// the stretch repository.
|
|
||||||
// I noticed that the first measure is the one that matters in
|
|
||||||
// practice. Here, we use a RefCell to store the cached measurement.
|
|
||||||
let measure = RefCell::new(None);
|
|
||||||
let size = text.size.map(f32::from).unwrap_or(DEFAULT_TEXT_SIZE);
|
|
||||||
|
|
||||||
let style = Style::default().width(text.width);
|
|
||||||
|
|
||||||
iced_native::Node::with_measure(style, move |bounds| {
|
|
||||||
let mut measure = measure.borrow_mut();
|
|
||||||
|
|
||||||
if measure.is_none() {
|
|
||||||
let bounds = (
|
|
||||||
match bounds.width {
|
|
||||||
iced_native::Number::Undefined => f32::INFINITY,
|
|
||||||
iced_native::Number::Defined(w) => w,
|
|
||||||
},
|
|
||||||
match bounds.height {
|
|
||||||
iced_native::Number::Undefined => f32::INFINITY,
|
|
||||||
iced_native::Number::Defined(h) => h,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let text = Section {
|
|
||||||
text: &content,
|
|
||||||
scale: wgpu_glyph::Scale { x: size, y: size },
|
|
||||||
bounds,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (width, height) = if let Some(bounds) =
|
|
||||||
glyph_brush.borrow_mut().glyph_bounds(&text)
|
|
||||||
{
|
|
||||||
(bounds.width().ceil(), bounds.height().ceil())
|
|
||||||
} else {
|
|
||||||
(0.0, 0.0)
|
|
||||||
};
|
|
||||||
|
|
||||||
let size = iced_native::Size { width, height };
|
|
||||||
|
|
||||||
// If the text has no width boundary we avoid caching as the
|
|
||||||
// layout engine may just be measuring text in a row.
|
|
||||||
if bounds.0 == f32::INFINITY {
|
|
||||||
return size;
|
|
||||||
} else {
|
|
||||||
*measure = Some(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
measure.unwrap()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self, text: &Text, layout: Layout<'_>) -> Self::Output {
|
fn draw(&mut self, text: &Text, layout: &Layout) -> Self::Output {
|
||||||
(
|
(
|
||||||
Primitive::Text {
|
Primitive::Text {
|
||||||
content: text.content.clone(),
|
content: text.content.clone(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue