Draft web runtime and widgets
This commit is contained in:
parent
a97401aed2
commit
27ac85a9d9
16 changed files with 321 additions and 29 deletions
16
web/src/color.rs
Normal file
16
web/src/color.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Color {
|
||||
pub r: f32,
|
||||
pub g: f32,
|
||||
pub b: f32,
|
||||
pub a: f32,
|
||||
}
|
||||
|
||||
impl Color {
|
||||
pub const BLACK: Color = Color {
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 1.0,
|
||||
};
|
||||
}
|
||||
47
web/src/element.rs
Normal file
47
web/src/element.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use crate::{Color, Widget};
|
||||
|
||||
pub struct Element<'a, Message> {
|
||||
pub(crate) widget: Box<dyn Widget<Message> + 'a>,
|
||||
}
|
||||
|
||||
impl<'a, Message> Element<'a, Message> {
|
||||
pub fn new(widget: impl Widget<Message> + 'a) -> Self {
|
||||
Self {
|
||||
widget: Box::new(widget),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn explain(self, color: Color) -> Element<'a, Message> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn map<F, B>(self, f: F) -> Element<'a, B>
|
||||
where
|
||||
Message: 'static,
|
||||
B: 'static,
|
||||
F: 'static + Fn(Message) -> B,
|
||||
{
|
||||
Element {
|
||||
widget: Box::new(Map::new(self.widget, f)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Map<'a, A, B> {
|
||||
widget: Box<dyn Widget<A> + 'a>,
|
||||
mapper: Box<dyn Fn(A) -> B>,
|
||||
}
|
||||
|
||||
impl<'a, A, B> Map<'a, A, B> {
|
||||
pub fn new<F>(widget: Box<dyn Widget<A> + 'a>, mapper: F) -> Map<'a, A, B>
|
||||
where
|
||||
F: 'static + Fn(A) -> B,
|
||||
{
|
||||
Map {
|
||||
widget,
|
||||
mapper: Box::new(mapper),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, A, B> Widget<B> for Map<'a, A, B> {}
|
||||
|
|
@ -1 +1,28 @@
|
|||
use futures::Future;
|
||||
|
||||
mod color;
|
||||
mod element;
|
||||
mod widget;
|
||||
|
||||
pub use color::Color;
|
||||
pub use element::Element;
|
||||
pub use iced::Align;
|
||||
pub use widget::*;
|
||||
|
||||
pub trait UserInterface {
|
||||
type Message;
|
||||
|
||||
fn update(
|
||||
&mut self,
|
||||
message: Self::Message,
|
||||
) -> Box<dyn Future<Item = Self::Message, Error = ()>>;
|
||||
|
||||
fn view(&mut self) -> Element<Self::Message>;
|
||||
|
||||
fn run(mut self)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let element = self.view();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
web/src/widget.rs
Normal file
20
web/src/widget.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
pub mod button;
|
||||
pub mod slider;
|
||||
pub mod text;
|
||||
|
||||
mod checkbox;
|
||||
mod column;
|
||||
mod image;
|
||||
mod radio;
|
||||
mod row;
|
||||
|
||||
pub use button::Button;
|
||||
pub use checkbox::Checkbox;
|
||||
pub use column::Column;
|
||||
pub use image::Image;
|
||||
pub use radio::Radio;
|
||||
pub use row::Row;
|
||||
pub use slider::Slider;
|
||||
pub use text::Text;
|
||||
|
||||
pub trait Widget<Message> {}
|
||||
16
web/src/widget/button.rs
Normal file
16
web/src/widget/button.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use crate::{Element, Widget};
|
||||
|
||||
pub use iced::button::{Class, State};
|
||||
|
||||
pub type Button<'a, Message> = iced::Button<'a, Message>;
|
||||
|
||||
impl<'a, Message> Widget<Message> for Button<'a, Message> {}
|
||||
|
||||
impl<'a, Message> From<Button<'a, Message>> for Element<'a, Message>
|
||||
where
|
||||
Message: 'static,
|
||||
{
|
||||
fn from(button: Button<'a, Message>) -> Element<'a, Message> {
|
||||
Element::new(button)
|
||||
}
|
||||
}
|
||||
14
web/src/widget/checkbox.rs
Normal file
14
web/src/widget/checkbox.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use crate::{Color, Element, Widget};
|
||||
|
||||
pub type Checkbox<Message> = iced::Checkbox<Color, Message>;
|
||||
|
||||
impl<Message> Widget<Message> for Checkbox<Message> {}
|
||||
|
||||
impl<'a, Message> From<Checkbox<Message>> for Element<'a, Message>
|
||||
where
|
||||
Message: 'static,
|
||||
{
|
||||
fn from(checkbox: Checkbox<Message>) -> Element<'a, Message> {
|
||||
Element::new(checkbox)
|
||||
}
|
||||
}
|
||||
48
web/src/widget/column.rs
Normal file
48
web/src/widget/column.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use crate::{Align, Element, Widget};
|
||||
|
||||
pub struct Column<'a, Message> {
|
||||
children: Vec<Element<'a, Message>>,
|
||||
}
|
||||
|
||||
impl<'a, Message> Column<'a, Message> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
children: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spacing(self, _spacing: u16) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn padding(self, _padding: u16) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn max_width(self, _max_width: u16) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn align_items(self, _align: Align) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn push<E>(mut self, element: E) -> Self
|
||||
where
|
||||
E: Into<Element<'a, Message>>,
|
||||
{
|
||||
self.children.push(element.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message> Widget<Message> for Column<'a, Message> {}
|
||||
|
||||
impl<'a, Message> From<Column<'a, Message>> for Element<'a, Message>
|
||||
where
|
||||
Message: 'static,
|
||||
{
|
||||
fn from(column: Column<'a, Message>) -> Element<'a, Message> {
|
||||
Element::new(column)
|
||||
}
|
||||
}
|
||||
11
web/src/widget/image.rs
Normal file
11
web/src/widget/image.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
use crate::{Element, Widget};
|
||||
|
||||
pub type Image<'a> = iced::Image<&'a str>;
|
||||
|
||||
impl<'a, Message> Widget<Message> for Image<'a> {}
|
||||
|
||||
impl<'a, Message> From<Image<'a>> for Element<'a, Message> {
|
||||
fn from(image: Image<'a>) -> Element<'a, Message> {
|
||||
Element::new(image)
|
||||
}
|
||||
}
|
||||
14
web/src/widget/radio.rs
Normal file
14
web/src/widget/radio.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use crate::{Color, Element, Widget};
|
||||
|
||||
pub type Radio<Message> = iced::Radio<Color, Message>;
|
||||
|
||||
impl<Message> Widget<Message> for Radio<Message> {}
|
||||
|
||||
impl<'a, Message> From<Radio<Message>> for Element<'a, Message>
|
||||
where
|
||||
Message: 'static,
|
||||
{
|
||||
fn from(radio: Radio<Message>) -> Element<'a, Message> {
|
||||
Element::new(radio)
|
||||
}
|
||||
}
|
||||
36
web/src/widget/row.rs
Normal file
36
web/src/widget/row.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
use crate::{Element, Widget};
|
||||
|
||||
pub struct Row<'a, Message> {
|
||||
children: Vec<Element<'a, Message>>,
|
||||
}
|
||||
|
||||
impl<'a, Message> Row<'a, Message> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
children: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spacing(self, _spacing: u16) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn push<E>(mut self, element: E) -> Self
|
||||
where
|
||||
E: Into<Element<'a, Message>>,
|
||||
{
|
||||
self.children.push(element.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message> Widget<Message> for Row<'a, Message> {}
|
||||
|
||||
impl<'a, Message> From<Row<'a, Message>> for Element<'a, Message>
|
||||
where
|
||||
Message: 'static,
|
||||
{
|
||||
fn from(column: Row<'a, Message>) -> Element<'a, Message> {
|
||||
Element::new(column)
|
||||
}
|
||||
}
|
||||
16
web/src/widget/slider.rs
Normal file
16
web/src/widget/slider.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use crate::{Element, Widget};
|
||||
|
||||
pub use iced::slider::State;
|
||||
|
||||
pub type Slider<'a, Message> = iced::Slider<'a, Message>;
|
||||
|
||||
impl<'a, Message> Widget<Message> for Slider<'a, Message> {}
|
||||
|
||||
impl<'a, Message> From<Slider<'a, Message>> for Element<'a, Message>
|
||||
where
|
||||
Message: 'static,
|
||||
{
|
||||
fn from(slider: Slider<'a, Message>) -> Element<'a, Message> {
|
||||
Element::new(slider)
|
||||
}
|
||||
}
|
||||
13
web/src/widget/text.rs
Normal file
13
web/src/widget/text.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use crate::{Color, Element, Widget};
|
||||
|
||||
pub use iced::text::HorizontalAlignment;
|
||||
|
||||
pub type Text = iced::Text<Color>;
|
||||
|
||||
impl<'a, Message> Widget<Message> for Text {}
|
||||
|
||||
impl<'a, Message> From<Text> for Element<'a, Message> {
|
||||
fn from(text: Text) -> Element<'a, Message> {
|
||||
Element::new(text)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue