Merge branch 'hecrj:master' into upgrade-wgpu

This commit is contained in:
Aaron Housh 2021-05-19 07:14:26 -07:00
commit ae484429d3
13 changed files with 104 additions and 50 deletions

View File

@ -6,4 +6,4 @@ edition = "2018"
publish = false publish = false
[dependencies] [dependencies]
iced = { path = "../.." } iced = { path = "../..", features = ["debug"] }

View File

@ -1,8 +1,8 @@
mod style; mod style;
use iced::{ use iced::{
scrollable, Column, Container, Element, Length, Radio, Row, Rule, Sandbox, button, scrollable, Button, Column, Container, Element, Length, Radio, Row,
Scrollable, Settings, Space, Text, Rule, Sandbox, Scrollable, Settings, Space, Text,
}; };
pub fn main() -> iced::Result { pub fn main() -> iced::Result {
@ -63,8 +63,10 @@ impl Sandbox for ScrollableDemo {
variants variants
.iter_mut() .iter_mut()
.map(|variant| { .map(|variant| {
let mut scrollable = Scrollable::new(&mut variant.state) let mut scrollable =
Scrollable::new(&mut variant.scrollable)
.padding(10) .padding(10)
.spacing(10)
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
.style(*theme) .style(*theme)
@ -108,6 +110,14 @@ impl Sandbox for ScrollableDemo {
.push(Space::with_height(Length::Units(1200))) .push(Space::with_height(Length::Units(1200)))
.push(Text::new("Middle")) .push(Text::new("Middle"))
.push(Space::with_height(Length::Units(1200))) .push(Space::with_height(Length::Units(1200)))
.push(
Button::new(
&mut variant.button,
Text::new("I am a button"),
)
.width(Length::Fill)
.padding(10),
)
.push(Text::new("The End.")); .push(Text::new("The End."));
Container::new(scrollable) Container::new(scrollable)
@ -142,7 +152,8 @@ impl Sandbox for ScrollableDemo {
/// A version of a scrollable /// A version of a scrollable
struct Variant { struct Variant {
title: &'static str, title: &'static str,
state: scrollable::State, scrollable: scrollable::State,
button: button::State,
scrollbar_width: Option<u16>, scrollbar_width: Option<u16>,
scrollbar_margin: Option<u16>, scrollbar_margin: Option<u16>,
scroller_width: Option<u16>, scroller_width: Option<u16>,
@ -153,28 +164,32 @@ impl Variant {
vec![ vec![
Self { Self {
title: "Default Scrollbar", title: "Default Scrollbar",
state: scrollable::State::new(), scrollable: scrollable::State::new(),
button: button::State::new(),
scrollbar_width: None, scrollbar_width: None,
scrollbar_margin: None, scrollbar_margin: None,
scroller_width: None, scroller_width: None,
}, },
Self { Self {
title: "Slimmed & Margin", title: "Slimmed & Margin",
state: scrollable::State::new(), scrollable: scrollable::State::new(),
button: button::State::new(),
scrollbar_width: Some(4), scrollbar_width: Some(4),
scrollbar_margin: Some(3), scrollbar_margin: Some(3),
scroller_width: Some(4), scroller_width: Some(4),
}, },
Self { Self {
title: "Wide Scroller", title: "Wide Scroller",
state: scrollable::State::new(), scrollable: scrollable::State::new(),
button: button::State::new(),
scrollbar_width: Some(4), scrollbar_width: Some(4),
scrollbar_margin: None, scrollbar_margin: None,
scroller_width: Some(10), scroller_width: Some(10),
}, },
Self { Self {
title: "Narrow Scroller", title: "Narrow Scroller",
state: scrollable::State::new(), scrollable: scrollable::State::new(),
button: button::State::new(),
scrollbar_width: Some(10), scrollbar_width: Some(10),
scrollbar_margin: None, scrollbar_margin: None,
scroller_width: Some(4), scroller_width: Some(4),

View File

@ -134,8 +134,16 @@ where
Primitive::None Primitive::None
}; };
let scroll = Primitive::Clip {
bounds,
offset: Vector::new(0, 0),
content: Box::new(Primitive::Group {
primitives: vec![scrollbar, scroller],
}),
};
Primitive::Group { Primitive::Group {
primitives: vec![clip, scrollbar, scroller], primitives: vec![clip, scroll],
} }
} else { } else {
content content

View File

@ -17,7 +17,10 @@ pub trait Compositor: Sized {
type SwapChain; type SwapChain;
/// Creates a new [`Compositor`]. /// Creates a new [`Compositor`].
fn new(settings: Self::Settings) -> Result<(Self, Self::Renderer), Error>; fn new<W: HasRawWindowHandle>(
settings: Self::Settings,
compatible_window: Option<&W>,
) -> Result<(Self, Self::Renderer), Error>;
/// Crates a new [`Surface`] for the given window. /// Crates a new [`Surface`] for the given window.
/// ///

View File

@ -8,8 +8,8 @@ use crate::row;
use crate::text; use crate::text;
use crate::touch; use crate::touch;
use crate::{ use crate::{
Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length, Align, Clipboard, Color, Element, Hasher, HorizontalAlignment, Layout,
Point, Rectangle, Row, Text, VerticalAlignment, Widget, Length, Point, Rectangle, Row, Text, VerticalAlignment, Widget,
}; };
/// A box that can be checked. /// A box that can be checked.
@ -39,6 +39,7 @@ pub struct Checkbox<Message, Renderer: self::Renderer + text::Renderer> {
spacing: u16, spacing: u16,
text_size: Option<u16>, text_size: Option<u16>,
font: Renderer::Font, font: Renderer::Font,
text_color: Option<Color>,
style: Renderer::Style, style: Renderer::Style,
} }
@ -66,6 +67,7 @@ impl<Message, Renderer: self::Renderer + text::Renderer>
spacing: Renderer::DEFAULT_SPACING, spacing: Renderer::DEFAULT_SPACING,
text_size: None, text_size: None,
font: Renderer::Font::default(), font: Renderer::Font::default(),
text_color: None,
style: Renderer::Style::default(), style: Renderer::Style::default(),
} }
} }
@ -102,6 +104,12 @@ impl<Message, Renderer: self::Renderer + text::Renderer>
self self
} }
/// Sets the text color of the [`Checkbox`] button.
pub fn text_color(mut self, color: Color) -> Self {
self.text_color = Some(color);
self
}
/// Sets the style of the [`Checkbox`]. /// Sets the style of the [`Checkbox`].
pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self { pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self {
self.style = style.into(); self.style = style.into();
@ -193,7 +201,7 @@ where
&self.label, &self.label,
self.text_size.unwrap_or(renderer.default_size()), self.text_size.unwrap_or(renderer.default_size()),
self.font, self.font,
None, self.text_color,
HorizontalAlignment::Left, HorizontalAlignment::Left,
VerticalAlignment::Center, VerticalAlignment::Center,
); );

View File

@ -163,7 +163,7 @@ where
let (width, _) = renderer.measure( let (width, _) = renderer.measure(
&label, &label,
text_size, text_size,
Renderer::Font::default(), self.font,
Size::new(f32::INFINITY, f32::INFINITY), Size::new(f32::INFINITY, f32::INFINITY),
); );

View File

@ -1,17 +1,17 @@
//! Create choices using radio buttons. //! Create choices using radio buttons.
use std::hash::Hash;
use crate::event::{self, Event}; use crate::event::{self, Event};
use crate::layout;
use crate::mouse; use crate::mouse;
use crate::row; use crate::row;
use crate::text; use crate::text;
use crate::touch; use crate::touch;
use crate::{layout, Color};
use crate::{ use crate::{
Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length, Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length,
Point, Rectangle, Row, Text, VerticalAlignment, Widget, Point, Rectangle, Row, Text, VerticalAlignment, Widget,
}; };
use std::hash::Hash;
/// A circular button representing a choice. /// A circular button representing a choice.
/// ///
/// # Example /// # Example
@ -47,6 +47,8 @@ pub struct Radio<Message, Renderer: self::Renderer + text::Renderer> {
size: u16, size: u16,
spacing: u16, spacing: u16,
text_size: Option<u16>, text_size: Option<u16>,
text_color: Option<Color>,
font: Renderer::Font,
style: Renderer::Style, style: Renderer::Style,
} }
@ -81,6 +83,8 @@ where
size: <Renderer as self::Renderer>::DEFAULT_SIZE, size: <Renderer as self::Renderer>::DEFAULT_SIZE,
spacing: Renderer::DEFAULT_SPACING, //15 spacing: Renderer::DEFAULT_SPACING, //15
text_size: None, text_size: None,
text_color: None,
font: Default::default(),
style: Renderer::Style::default(), style: Renderer::Style::default(),
} }
} }
@ -109,6 +113,18 @@ where
self self
} }
/// Sets the text color of the [`Radio`] button.
pub fn text_color(mut self, color: Color) -> Self {
self.text_color = Some(color);
self
}
/// Sets the text font of the [`Radio`] button.
pub fn font(mut self, font: Renderer::Font) -> Self {
self.font = font;
self
}
/// Sets the style of the [`Radio`] button. /// Sets the style of the [`Radio`] button.
pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self { pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self {
self.style = style.into(); self.style = style.into();
@ -196,8 +212,8 @@ where
label_layout.bounds(), label_layout.bounds(),
&self.label, &self.label,
self.text_size.unwrap_or(renderer.default_size()), self.text_size.unwrap_or(renderer.default_size()),
Default::default(), self.font,
None, self.text_color,
HorizontalAlignment::Left, HorizontalAlignment::Left,
VerticalAlignment::Center, VerticalAlignment::Center,
); );

View File

@ -1 +1,2 @@
max_width=80 max_width=80
edition="2018"

View File

@ -30,7 +30,7 @@
//! [windowing shell]: https://github.com/hecrj/iced/tree/master/winit //! [windowing shell]: https://github.com/hecrj/iced/tree/master/winit
//! [`dodrio`]: https://github.com/fitzgen/dodrio //! [`dodrio`]: https://github.com/fitzgen/dodrio
//! [web runtime]: https://github.com/hecrj/iced/tree/master/web //! [web runtime]: https://github.com/hecrj/iced/tree/master/web
//! [examples]: https://github.com/hecrj/iced/tree/0.2/examples //! [examples]: https://github.com/hecrj/iced/tree/0.3/examples
//! [repository]: https://github.com/hecrj/iced //! [repository]: https://github.com/hecrj/iced
//! //!
//! # Overview //! # Overview

View File

@ -1,7 +1,8 @@
use crate::image::atlas::{self, Atlas};
use iced_native::svg; use iced_native::svg;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use crate::image::atlas::{self, Atlas};
pub enum Svg { pub enum Svg {
Loaded(usvg::Tree), Loaded(usvg::Tree),
NotFound, NotFound,
@ -111,26 +112,13 @@ impl Cache {
let width = img.width(); let width = img.width();
let height = img.height(); let height = img.height();
let mut rgba = img.take().into_iter(); let mut rgba = img.take();
rgba.chunks_exact_mut(4).for_each(|rgba| rgba.swap(0, 2));
// TODO: Perform conversion in the GPU
let bgra: Vec<u8> = std::iter::from_fn(move || {
use std::iter::once;
let r = rgba.next()?;
let g = rgba.next()?;
let b = rgba.next()?;
let a = rgba.next()?;
Some(once(b).chain(once(g)).chain(once(r)).chain(once(a)))
})
.flatten()
.collect();
let allocation = texture_atlas.upload( let allocation = texture_atlas.upload(
width, width,
height, height,
bytemuck::cast_slice(bgra.as_slice()), bytemuck::cast_slice(rgba.as_slice()),
device, device,
encoder, encoder,
)?; )?;

View File

@ -47,6 +47,7 @@ impl Settings {
/// - `dx11` /// - `dx11`
/// - `gl` /// - `gl`
/// - `webgpu` /// - `webgpu`
/// - `primary`
pub fn from_env() -> Self { pub fn from_env() -> Self {
Settings { Settings {
internal_backend: backend_from_env() internal_backend: backend_from_env()
@ -78,6 +79,7 @@ fn backend_from_env() -> Option<wgpu::BackendBit> {
"dx11" => wgpu::BackendBit::DX11, "dx11" => wgpu::BackendBit::DX11,
"gl" => wgpu::BackendBit::GL, "gl" => wgpu::BackendBit::GL,
"webgpu" => wgpu::BackendBit::BROWSER_WEBGPU, "webgpu" => wgpu::BackendBit::BROWSER_WEBGPU,
"primary" => wgpu::BackendBit::PRIMARY,
other => panic!("Unknown backend: {}", other), other => panic!("Unknown backend: {}", other),
} }
}) })

View File

@ -21,9 +21,16 @@ impl Compositor {
/// Requests a new [`Compositor`] with the given [`Settings`]. /// Requests a new [`Compositor`] with the given [`Settings`].
/// ///
/// Returns `None` if no compatible graphics adapter could be found. /// Returns `None` if no compatible graphics adapter could be found.
pub async fn request(settings: Settings) -> Option<Self> { pub async fn request<W: HasRawWindowHandle>(
settings: Settings,
compatible_window: Option<&W>,
) -> Option<Self> {
let instance = wgpu::Instance::new(settings.internal_backend); let instance = wgpu::Instance::new(settings.internal_backend);
#[allow(unsafe_code)]
let compatible_surface = compatible_window
.map(|window| unsafe { instance.create_surface(window) });
let adapter = instance let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions { .request_adapter(&wgpu::RequestAdapterOptions {
power_preference: if settings.antialiasing.is_none() { power_preference: if settings.antialiasing.is_none() {
@ -31,7 +38,7 @@ impl Compositor {
} else { } else {
wgpu::PowerPreference::HighPerformance wgpu::PowerPreference::HighPerformance
}, },
compatible_surface: None, compatible_surface: compatible_surface.as_ref(),
}) })
.await?; .await?;
@ -77,8 +84,14 @@ impl iced_graphics::window::Compositor for Compositor {
type Surface = wgpu::Surface; type Surface = wgpu::Surface;
type SwapChain = wgpu::SwapChain; type SwapChain = wgpu::SwapChain;
fn new(settings: Self::Settings) -> Result<(Self, Renderer), Error> { fn new<W: HasRawWindowHandle>(
let compositor = futures::executor::block_on(Self::request(settings)) settings: Self::Settings,
compatible_window: Option<&W>,
) -> Result<(Self, Renderer), Error> {
let compositor = futures::executor::block_on(Self::request(
settings,
compatible_window,
))
.ok_or(Error::AdapterNotFound)?; .ok_or(Error::AdapterNotFound)?;
let backend = compositor.create_backend(); let backend = compositor.create_backend();

View File

@ -118,8 +118,6 @@ where
let mut debug = Debug::new(); let mut debug = Debug::new();
debug.startup_started(); debug.startup_started();
let (compositor, renderer) = C::new(compositor_settings)?;
let event_loop = EventLoop::with_user_event(); let event_loop = EventLoop::with_user_event();
let mut runtime = { let mut runtime = {
@ -150,6 +148,8 @@ where
.build(&event_loop) .build(&event_loop)
.map_err(Error::WindowCreationFailed)?; .map_err(Error::WindowCreationFailed)?;
let (compositor, renderer) = C::new(compositor_settings, Some(&window))?;
let (mut sender, receiver) = mpsc::unbounded(); let (mut sender, receiver) = mpsc::unbounded();
let mut instance = Box::pin(run_instance::<A, E, C>( let mut instance = Box::pin(run_instance::<A, E, C>(