Merge pull request #1284 from iced-rs/virtual-widgets
Stateless widgets
This commit is contained in:
commit
0eef527fa5
140 changed files with 12733 additions and 2709 deletions
|
|
@ -1,12 +1,13 @@
|
|||
//! Organize rendering primitives into a flattened list of layers.
|
||||
use crate::alignment;
|
||||
use crate::image;
|
||||
use crate::svg;
|
||||
use crate::triangle;
|
||||
use crate::{
|
||||
Background, Font, Point, Primitive, Rectangle, Size, Vector, Viewport,
|
||||
};
|
||||
|
||||
use iced_native::image;
|
||||
use iced_native::svg;
|
||||
|
||||
/// A group of primitives that should be clipped together.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Layer<'a> {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
//! Create a renderer from a [`Backend`].
|
||||
use crate::backend::{self, Backend};
|
||||
use crate::{Primitive, Vector};
|
||||
use iced_native::image;
|
||||
use iced_native::layout;
|
||||
use iced_native::renderer;
|
||||
use iced_native::svg;
|
||||
use iced_native::text::{self, Text};
|
||||
use iced_native::{Background, Element, Font, Point, Rectangle, Size};
|
||||
|
||||
|
|
@ -168,3 +170,31 @@ where
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> image::Renderer for Renderer<B>
|
||||
where
|
||||
B: Backend + backend::Image,
|
||||
{
|
||||
type Handle = image::Handle;
|
||||
|
||||
fn dimensions(&self, handle: &image::Handle) -> (u32, u32) {
|
||||
self.backend().dimensions(handle)
|
||||
}
|
||||
|
||||
fn draw(&mut self, handle: image::Handle, bounds: Rectangle) {
|
||||
self.draw_primitive(Primitive::Image { handle, bounds })
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> svg::Renderer for Renderer<B>
|
||||
where
|
||||
B: Backend + backend::Svg,
|
||||
{
|
||||
fn dimensions(&self, handle: &svg::Handle) -> (u32, u32) {
|
||||
self.backend().viewport_dimensions(handle)
|
||||
}
|
||||
|
||||
fn draw(&mut self, handle: svg::Handle, bounds: Rectangle) {
|
||||
self.draw_primitive(Primitive::Svg { handle, bounds })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +1,4 @@
|
|||
//! Use the widgets supported out-of-the-box.
|
||||
//!
|
||||
//! # Re-exports
|
||||
//! For convenience, the contents of this module are available at the root
|
||||
//! module. Therefore, you can directly type:
|
||||
//!
|
||||
//! ```
|
||||
//! use iced_graphics::{button, Button};
|
||||
//! ```
|
||||
pub mod button;
|
||||
pub mod checkbox;
|
||||
pub mod container;
|
||||
pub mod image;
|
||||
pub mod pane_grid;
|
||||
pub mod pick_list;
|
||||
pub mod progress_bar;
|
||||
pub mod radio;
|
||||
pub mod rule;
|
||||
pub mod scrollable;
|
||||
pub mod slider;
|
||||
pub mod svg;
|
||||
pub mod text_input;
|
||||
pub mod toggler;
|
||||
pub mod tooltip;
|
||||
|
||||
mod column;
|
||||
mod row;
|
||||
mod space;
|
||||
mod text;
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use button::Button;
|
||||
#[doc(no_inline)]
|
||||
pub use checkbox::Checkbox;
|
||||
#[doc(no_inline)]
|
||||
pub use container::Container;
|
||||
#[doc(no_inline)]
|
||||
pub use pane_grid::PaneGrid;
|
||||
#[doc(no_inline)]
|
||||
pub use pick_list::PickList;
|
||||
#[doc(no_inline)]
|
||||
pub use progress_bar::ProgressBar;
|
||||
#[doc(no_inline)]
|
||||
pub use radio::Radio;
|
||||
#[doc(no_inline)]
|
||||
pub use rule::Rule;
|
||||
#[doc(no_inline)]
|
||||
pub use scrollable::Scrollable;
|
||||
#[doc(no_inline)]
|
||||
pub use slider::Slider;
|
||||
#[doc(no_inline)]
|
||||
pub use text_input::TextInput;
|
||||
#[doc(no_inline)]
|
||||
pub use toggler::Toggler;
|
||||
#[doc(no_inline)]
|
||||
pub use tooltip::Tooltip;
|
||||
|
||||
pub use column::Column;
|
||||
pub use image::Image;
|
||||
pub use row::Row;
|
||||
pub use space::Space;
|
||||
pub use svg::Svg;
|
||||
pub use text::Text;
|
||||
|
||||
//! Use the graphical widgets supported out-of-the-box.
|
||||
#[cfg(feature = "canvas")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))]
|
||||
pub mod canvas;
|
||||
|
|
@ -77,3 +14,6 @@ pub mod qr_code;
|
|||
#[cfg(feature = "qr_code")]
|
||||
#[doc(no_inline)]
|
||||
pub use qr_code::QRCode;
|
||||
|
||||
#[cfg(feature = "pure")]
|
||||
pub mod pure;
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
//! Allow your users to perform actions by pressing a button.
|
||||
//!
|
||||
//! A [`Button`] has some local [`State`].
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_native::widget::button::{State, Style, StyleSheet};
|
||||
|
||||
/// A widget that produces a message when clicked.
|
||||
///
|
||||
/// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`.
|
||||
pub type Button<'a, Message, Backend> =
|
||||
iced_native::widget::Button<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -6,14 +6,6 @@
|
|||
use crate::renderer::{self, Renderer};
|
||||
use crate::{Backend, Primitive};
|
||||
|
||||
use iced_native::layout;
|
||||
use iced_native::mouse;
|
||||
use iced_native::{
|
||||
Clipboard, Element, Layout, Length, Point, Rectangle, Shell, Size, Vector,
|
||||
Widget,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub mod event;
|
||||
pub mod path;
|
||||
|
||||
|
|
@ -37,6 +29,15 @@ pub use program::Program;
|
|||
pub use stroke::{LineCap, LineDash, LineJoin, Stroke};
|
||||
pub use text::Text;
|
||||
|
||||
use iced_native::layout;
|
||||
use iced_native::mouse;
|
||||
use iced_native::{
|
||||
Clipboard, Element, Layout, Length, Point, Rectangle, Shell, Size, Vector,
|
||||
Widget,
|
||||
};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// A widget capable of drawing 2D graphics.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
@ -97,7 +98,7 @@ pub struct Canvas<Message, P: Program<Message>> {
|
|||
width: Length,
|
||||
height: Length,
|
||||
program: P,
|
||||
phantom: PhantomData<Message>,
|
||||
message_: PhantomData<Message>,
|
||||
}
|
||||
|
||||
impl<Message, P: Program<Message>> Canvas<Message, P> {
|
||||
|
|
@ -109,7 +110,7 @@ impl<Message, P: Program<Message>> Canvas<Message, P> {
|
|||
width: Length::Units(Self::DEFAULT_SIZE),
|
||||
height: Length::Units(Self::DEFAULT_SIZE),
|
||||
program,
|
||||
phantom: PhantomData,
|
||||
message_: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
//! Show toggle controls using checkboxes.
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_style::checkbox::{Style, StyleSheet};
|
||||
|
||||
/// A box that can be checked.
|
||||
///
|
||||
/// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`.
|
||||
pub type Checkbox<'a, Message, Backend> =
|
||||
iced_native::widget::Checkbox<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
use crate::Renderer;
|
||||
|
||||
/// A container that distributes its contents vertically.
|
||||
pub type Column<'a, Message, Backend> =
|
||||
iced_native::widget::Column<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
//! Decorate content and apply alignment.
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_style::container::{Style, StyleSheet};
|
||||
|
||||
/// An element decorating some content.
|
||||
///
|
||||
/// This is an alias of an `iced_native` container with a default
|
||||
/// `Renderer`.
|
||||
pub type Container<'a, Message, Backend> =
|
||||
iced_native::widget::Container<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
//! Display images in your user interface.
|
||||
pub mod viewer;
|
||||
|
||||
use crate::backend::{self, Backend};
|
||||
use crate::{Primitive, Rectangle, Renderer};
|
||||
|
||||
use iced_native::image;
|
||||
|
||||
pub use iced_native::widget::image::{Image, Viewer};
|
||||
pub use image::Handle;
|
||||
|
||||
impl<B> image::Renderer for Renderer<B>
|
||||
where
|
||||
B: Backend + backend::Image,
|
||||
{
|
||||
type Handle = image::Handle;
|
||||
|
||||
fn dimensions(&self, handle: &image::Handle) -> (u32, u32) {
|
||||
self.backend().dimensions(handle)
|
||||
}
|
||||
|
||||
fn draw(&mut self, handle: image::Handle, bounds: Rectangle) {
|
||||
self.draw_primitive(Primitive::Image { handle, bounds })
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
//! Zoom and pan on an image.
|
||||
pub use iced_native::widget::image::Viewer;
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
//! Let your users split regions of your application and organize layout dynamically.
|
||||
//!
|
||||
//! [](https://gfycat.com/mixedflatjellyfish)
|
||||
//!
|
||||
//! # Example
|
||||
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
|
||||
//! drag and drop, and hotkey support.
|
||||
//!
|
||||
//! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.3/examples/pane_grid
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_native::widget::pane_grid::{
|
||||
Axis, Configuration, Content, Direction, DragEvent, Node, Pane,
|
||||
ResizeEvent, Split, State, TitleBar,
|
||||
};
|
||||
|
||||
pub use iced_style::pane_grid::{Line, StyleSheet};
|
||||
|
||||
/// A collection of panes distributed using either vertical or horizontal splits
|
||||
/// to completely fill the space available.
|
||||
///
|
||||
/// [](https://gfycat.com/mixedflatjellyfish)
|
||||
///
|
||||
/// This is an alias of an `iced_native` pane grid with an `iced_wgpu::Renderer`.
|
||||
pub type PaneGrid<'a, Message, Backend> =
|
||||
iced_native::widget::PaneGrid<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
//! Display a dropdown list of selectable values.
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_native::widget::pick_list::State;
|
||||
pub use iced_style::pick_list::{Style, StyleSheet};
|
||||
|
||||
/// A widget allowing the selection of a single value from a list of options.
|
||||
pub type PickList<'a, T, Message, Backend> =
|
||||
iced_native::widget::PickList<'a, T, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
//! Allow your users to visually track the progress of a computation.
|
||||
//!
|
||||
//! A [`ProgressBar`] has a range of possible values and a current value,
|
||||
//! as well as a length, height and style.
|
||||
pub use iced_native::widget::progress_bar::*;
|
||||
12
graphics/src/widget/pure.rs
Normal file
12
graphics/src/widget/pure.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
//! Leverage pure, virtual widgets in your application.
|
||||
#[cfg(feature = "canvas")]
|
||||
pub mod canvas;
|
||||
|
||||
#[cfg(feature = "canvas")]
|
||||
pub use canvas::Canvas;
|
||||
|
||||
#[cfg(feature = "qr_code")]
|
||||
pub mod qr_code;
|
||||
|
||||
#[cfg(feature = "qr_code")]
|
||||
pub use qr_code::QRCode;
|
||||
237
graphics/src/widget/pure/canvas.rs
Normal file
237
graphics/src/widget/pure/canvas.rs
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
//! Draw 2D graphics for your users.
|
||||
//!
|
||||
//! A [`Canvas`] widget can be used to draw different kinds of 2D shapes in a
|
||||
//! [`Frame`]. It can be used for animation, data visualization, game graphics,
|
||||
//! and more!
|
||||
mod program;
|
||||
|
||||
pub use crate::widget::canvas::{Canvas as _, Program as _, *};
|
||||
|
||||
pub use program::Program;
|
||||
|
||||
use crate::{Backend, Primitive, Renderer};
|
||||
|
||||
use iced_native::layout::{self, Layout};
|
||||
use iced_native::mouse;
|
||||
use iced_native::renderer;
|
||||
use iced_native::{Clipboard, Length, Point, Rectangle, Shell, Size, Vector};
|
||||
use iced_pure::widget::tree::{self, Tree};
|
||||
use iced_pure::{Element, Widget};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// A widget capable of drawing 2D graphics.
|
||||
///
|
||||
/// ## Drawing a simple circle
|
||||
/// If you want to get a quick overview, here's how we can draw a simple circle:
|
||||
///
|
||||
/// ```no_run
|
||||
/// # mod iced {
|
||||
/// # pub mod pure {
|
||||
/// # pub use iced_graphics::pure::canvas;
|
||||
/// # }
|
||||
/// # pub use iced_native::{Color, Rectangle};
|
||||
/// # }
|
||||
/// use iced::pure::canvas::{self, Canvas, Cursor, Fill, Frame, Geometry, Path, Program};
|
||||
/// use iced::{Color, Rectangle};
|
||||
///
|
||||
/// // First, we define the data we need for drawing
|
||||
/// #[derive(Debug)]
|
||||
/// struct Circle {
|
||||
/// radius: f32,
|
||||
/// }
|
||||
///
|
||||
/// // Then, we implement the `Program` trait
|
||||
/// impl Program<()> for Circle {
|
||||
/// type State = ();
|
||||
///
|
||||
/// fn draw(&self, _state: &(), bounds: Rectangle, _cursor: Cursor) -> Vec<Geometry>{
|
||||
/// // We prepare a new `Frame`
|
||||
/// let mut frame = Frame::new(bounds.size());
|
||||
///
|
||||
/// // We create a `Path` representing a simple circle
|
||||
/// let circle = Path::circle(frame.center(), self.radius);
|
||||
///
|
||||
/// // And fill it with some color
|
||||
/// frame.fill(&circle, Color::BLACK);
|
||||
///
|
||||
/// // Finally, we produce the geometry
|
||||
/// vec![frame.into_geometry()]
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Finally, we simply use our `Circle` to create the `Canvas`!
|
||||
/// let canvas = Canvas::new(Circle { radius: 50.0 });
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct Canvas<Message, P>
|
||||
where
|
||||
P: Program<Message>,
|
||||
{
|
||||
width: Length,
|
||||
height: Length,
|
||||
program: P,
|
||||
message_: PhantomData<Message>,
|
||||
}
|
||||
|
||||
impl<Message, P> Canvas<Message, P>
|
||||
where
|
||||
P: Program<Message>,
|
||||
{
|
||||
const DEFAULT_SIZE: u16 = 100;
|
||||
|
||||
/// Creates a new [`Canvas`].
|
||||
pub fn new(program: P) -> Self {
|
||||
Canvas {
|
||||
width: Length::Units(Self::DEFAULT_SIZE),
|
||||
height: Length::Units(Self::DEFAULT_SIZE),
|
||||
program,
|
||||
message_: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the width of the [`Canvas`].
|
||||
pub fn width(mut self, width: Length) -> Self {
|
||||
self.width = width;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the height of the [`Canvas`].
|
||||
pub fn height(mut self, height: Length) -> Self {
|
||||
self.height = height;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Message, P, B> Widget<Message, Renderer<B>> for Canvas<Message, P>
|
||||
where
|
||||
P: Program<Message>,
|
||||
B: Backend,
|
||||
{
|
||||
fn tag(&self) -> tree::Tag {
|
||||
tree::Tag::of::<P::State>()
|
||||
}
|
||||
|
||||
fn state(&self) -> tree::State {
|
||||
tree::State::new(P::State::default())
|
||||
}
|
||||
|
||||
fn width(&self) -> Length {
|
||||
self.width
|
||||
}
|
||||
|
||||
fn height(&self) -> Length {
|
||||
self.height
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&self,
|
||||
_renderer: &Renderer<B>,
|
||||
limits: &layout::Limits,
|
||||
) -> layout::Node {
|
||||
let limits = limits.width(self.width).height(self.height);
|
||||
let size = limits.resolve(Size::ZERO);
|
||||
|
||||
layout::Node::new(size)
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
tree: &mut Tree,
|
||||
event: iced_native::Event,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
_renderer: &Renderer<B>,
|
||||
_clipboard: &mut dyn Clipboard,
|
||||
shell: &mut Shell<'_, Message>,
|
||||
) -> event::Status {
|
||||
let bounds = layout.bounds();
|
||||
|
||||
let canvas_event = match event {
|
||||
iced_native::Event::Mouse(mouse_event) => {
|
||||
Some(Event::Mouse(mouse_event))
|
||||
}
|
||||
iced_native::Event::Keyboard(keyboard_event) => {
|
||||
Some(Event::Keyboard(keyboard_event))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let cursor = Cursor::from_window_position(cursor_position);
|
||||
|
||||
if let Some(canvas_event) = canvas_event {
|
||||
let state = tree.state.downcast_mut::<P::State>();
|
||||
|
||||
let (event_status, message) =
|
||||
self.program.update(state, canvas_event, bounds, cursor);
|
||||
|
||||
if let Some(message) = message {
|
||||
shell.publish(message);
|
||||
}
|
||||
|
||||
return event_status;
|
||||
}
|
||||
|
||||
event::Status::Ignored
|
||||
}
|
||||
|
||||
fn mouse_interaction(
|
||||
&self,
|
||||
tree: &Tree,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
_viewport: &Rectangle,
|
||||
_renderer: &Renderer<B>,
|
||||
) -> mouse::Interaction {
|
||||
let bounds = layout.bounds();
|
||||
let cursor = Cursor::from_window_position(cursor_position);
|
||||
let state = tree.state.downcast_ref::<P::State>();
|
||||
|
||||
self.program.mouse_interaction(state, bounds, cursor)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
tree: &Tree,
|
||||
renderer: &mut Renderer<B>,
|
||||
_style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
_viewport: &Rectangle,
|
||||
) {
|
||||
use iced_native::Renderer as _;
|
||||
|
||||
let bounds = layout.bounds();
|
||||
|
||||
if bounds.width < 1.0 || bounds.height < 1.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let translation = Vector::new(bounds.x, bounds.y);
|
||||
let cursor = Cursor::from_window_position(cursor_position);
|
||||
let state = tree.state.downcast_ref::<P::State>();
|
||||
|
||||
renderer.with_translation(translation, |renderer| {
|
||||
renderer.draw_primitive(Primitive::Group {
|
||||
primitives: self
|
||||
.program
|
||||
.draw(state, bounds, cursor)
|
||||
.into_iter()
|
||||
.map(Geometry::into_primitive)
|
||||
.collect(),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, P, B> From<Canvas<Message, P>>
|
||||
for Element<'a, Message, Renderer<B>>
|
||||
where
|
||||
Message: 'a,
|
||||
P: Program<Message> + 'a,
|
||||
B: Backend,
|
||||
{
|
||||
fn from(canvas: Canvas<Message, P>) -> Element<'a, Message, Renderer<B>> {
|
||||
Element::new(canvas)
|
||||
}
|
||||
}
|
||||
100
graphics/src/widget/pure/canvas/program.rs
Normal file
100
graphics/src/widget/pure/canvas/program.rs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
use crate::widget::pure::canvas::event::{self, Event};
|
||||
use crate::widget::pure::canvas::mouse;
|
||||
use crate::widget::pure::canvas::{Cursor, Geometry};
|
||||
use crate::Rectangle;
|
||||
|
||||
/// The state and logic of a [`Canvas`].
|
||||
///
|
||||
/// A [`Program`] can mutate internal state and produce messages for an
|
||||
/// application.
|
||||
///
|
||||
/// [`Canvas`]: crate::widget::Canvas
|
||||
pub trait Program<Message> {
|
||||
/// The internal [`State`] mutated by the [`Program`].
|
||||
type State: Default + 'static;
|
||||
|
||||
/// Updates the state of the [`Program`].
|
||||
///
|
||||
/// When a [`Program`] is used in a [`Canvas`], the runtime will call this
|
||||
/// method for each [`Event`].
|
||||
///
|
||||
/// This method can optionally return a `Message` to notify an application
|
||||
/// of any meaningful interactions.
|
||||
///
|
||||
/// By default, this method does and returns nothing.
|
||||
///
|
||||
/// [`Canvas`]: crate::widget::Canvas
|
||||
fn update(
|
||||
&self,
|
||||
_state: &mut Self::State,
|
||||
_event: Event,
|
||||
_bounds: Rectangle,
|
||||
_cursor: Cursor,
|
||||
) -> (event::Status, Option<Message>) {
|
||||
(event::Status::Ignored, None)
|
||||
}
|
||||
|
||||
/// Draws the state of the [`Program`], producing a bunch of [`Geometry`].
|
||||
///
|
||||
/// [`Geometry`] can be easily generated with a [`Frame`] or stored in a
|
||||
/// [`Cache`].
|
||||
///
|
||||
/// [`Frame`]: crate::widget::canvas::Frame
|
||||
/// [`Cache`]: crate::widget::canvas::Cache
|
||||
fn draw(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> Vec<Geometry>;
|
||||
|
||||
/// Returns the current mouse interaction of the [`Program`].
|
||||
///
|
||||
/// The interaction returned will be in effect even if the cursor position
|
||||
/// is out of bounds of the program's [`Canvas`].
|
||||
///
|
||||
/// [`Canvas`]: crate::widget::Canvas
|
||||
fn mouse_interaction(
|
||||
&self,
|
||||
_state: &Self::State,
|
||||
_bounds: Rectangle,
|
||||
_cursor: Cursor,
|
||||
) -> mouse::Interaction {
|
||||
mouse::Interaction::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Message, T> Program<Message> for &T
|
||||
where
|
||||
T: Program<Message>,
|
||||
{
|
||||
type State = T::State;
|
||||
|
||||
fn update(
|
||||
&self,
|
||||
state: &mut Self::State,
|
||||
event: Event,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> (event::Status, Option<Message>) {
|
||||
T::update(self, state, event, bounds, cursor)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> Vec<Geometry> {
|
||||
T::draw(self, state, bounds, cursor)
|
||||
}
|
||||
|
||||
fn mouse_interaction(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> mouse::Interaction {
|
||||
T::mouse_interaction(self, state, bounds, cursor)
|
||||
}
|
||||
}
|
||||
61
graphics/src/widget/pure/qr_code.rs
Normal file
61
graphics/src/widget/pure/qr_code.rs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
//! Encode and display information in a QR code.
|
||||
pub use crate::qr_code::*;
|
||||
|
||||
use crate::{Backend, Renderer};
|
||||
|
||||
use iced_native::layout::{self, Layout};
|
||||
use iced_native::renderer;
|
||||
use iced_native::{Length, Point, Rectangle};
|
||||
use iced_pure::widget::tree::Tree;
|
||||
use iced_pure::{Element, Widget};
|
||||
|
||||
impl<'a, Message, B> Widget<Message, Renderer<B>> for QRCode<'a>
|
||||
where
|
||||
B: Backend,
|
||||
{
|
||||
fn width(&self) -> Length {
|
||||
<Self as iced_native::Widget<Message, Renderer<B>>>::width(self)
|
||||
}
|
||||
|
||||
fn height(&self) -> Length {
|
||||
<Self as iced_native::Widget<Message, Renderer<B>>>::height(self)
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&self,
|
||||
renderer: &Renderer<B>,
|
||||
limits: &layout::Limits,
|
||||
) -> layout::Node {
|
||||
<Self as iced_native::Widget<Message, Renderer<B>>>::layout(
|
||||
self, renderer, limits,
|
||||
)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
_tree: &Tree,
|
||||
renderer: &mut Renderer<B>,
|
||||
style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
viewport: &Rectangle,
|
||||
) {
|
||||
<Self as iced_native::Widget<Message, Renderer<B>>>::draw(
|
||||
self,
|
||||
renderer,
|
||||
style,
|
||||
layout,
|
||||
cursor_position,
|
||||
viewport,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, B> Into<Element<'a, Message, Renderer<B>>> for QRCode<'a>
|
||||
where
|
||||
B: Backend,
|
||||
{
|
||||
fn into(self) -> Element<'a, Message, Renderer<B>> {
|
||||
Element::new(self)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
//! Create choices using radio buttons.
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_style::radio::{Style, StyleSheet};
|
||||
|
||||
/// A circular button representing a choice.
|
||||
///
|
||||
/// This is an alias of an `iced_native` radio button with an
|
||||
/// `iced_wgpu::Renderer`.
|
||||
pub type Radio<'a, Message, Backend> =
|
||||
iced_native::widget::Radio<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
use crate::Renderer;
|
||||
|
||||
/// A container that distributes its contents horizontally.
|
||||
pub type Row<'a, Message, Backend> =
|
||||
iced_native::widget::Row<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
//! Display a horizontal or vertical rule for dividing content.
|
||||
|
||||
pub use iced_native::widget::rule::*;
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
//! Navigate an endless amount of content with a scrollbar.
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_native::widget::scrollable::State;
|
||||
pub use iced_style::scrollable::{Scrollbar, Scroller, StyleSheet};
|
||||
|
||||
/// A widget that can vertically display an infinite amount of content
|
||||
/// with a scrollbar.
|
||||
///
|
||||
/// This is an alias of an `iced_native` scrollable with a default
|
||||
/// `Renderer`.
|
||||
pub type Scrollable<'a, Message, Backend> =
|
||||
iced_native::widget::Scrollable<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
//! Display an interactive selector of a single value from a range of values.
|
||||
//!
|
||||
//! A [`Slider`] has some local [`State`].
|
||||
pub use iced_native::widget::slider::{Slider, State};
|
||||
pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet};
|
||||
|
|
@ -1 +0,0 @@
|
|||
pub use iced_native::widget::Space;
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
//! Display vector graphics in your application.
|
||||
use crate::backend::{self, Backend};
|
||||
use crate::{Primitive, Rectangle, Renderer};
|
||||
use iced_native::svg;
|
||||
|
||||
pub use iced_native::widget::svg::Svg;
|
||||
pub use svg::Handle;
|
||||
|
||||
impl<B> svg::Renderer for Renderer<B>
|
||||
where
|
||||
B: Backend + backend::Svg,
|
||||
{
|
||||
fn dimensions(&self, handle: &svg::Handle) -> (u32, u32) {
|
||||
self.backend().viewport_dimensions(handle)
|
||||
}
|
||||
|
||||
fn draw(&mut self, handle: svg::Handle, bounds: Rectangle) {
|
||||
self.draw_primitive(Primitive::Svg { handle, bounds })
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
//! Write some text for your users to read.
|
||||
use crate::Renderer;
|
||||
|
||||
/// A paragraph of text.
|
||||
///
|
||||
/// This is an alias of an `iced_native` text with an `iced_wgpu::Renderer`.
|
||||
pub type Text<Backend> = iced_native::widget::Text<Renderer<Backend>>;
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
//! Display fields that can be filled with text.
|
||||
//!
|
||||
//! A [`TextInput`] has some local [`State`].
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_native::widget::text_input::State;
|
||||
pub use iced_style::text_input::{Style, StyleSheet};
|
||||
|
||||
/// A field that can be filled with text.
|
||||
///
|
||||
/// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`.
|
||||
pub type TextInput<'a, Message, Backend> =
|
||||
iced_native::widget::TextInput<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
//! Show toggle controls using togglers.
|
||||
use crate::Renderer;
|
||||
|
||||
pub use iced_style::toggler::{Style, StyleSheet};
|
||||
|
||||
/// A toggler that can be toggled.
|
||||
///
|
||||
/// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`.
|
||||
pub type Toggler<'a, Message, Backend> =
|
||||
iced_native::widget::Toggler<'a, Message, Renderer<Backend>>;
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
//! Decorate content and apply alignment.
|
||||
use crate::Renderer;
|
||||
|
||||
/// An element decorating some content.
|
||||
///
|
||||
/// This is an alias of an `iced_native` tooltip with a default
|
||||
/// `Renderer`.
|
||||
pub type Tooltip<'a, Message, Backend> =
|
||||
iced_native::widget::Tooltip<'a, Message, Renderer<Backend>>;
|
||||
|
||||
pub use iced_native::widget::tooltip::Position;
|
||||
Loading…
Add table
Add a link
Reference in a new issue