Merge branch 'hecrj:master' into upgrade-wgpu
This commit is contained in:
commit
ae484429d3
@ -6,4 +6,4 @@ edition = "2018"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced = { path = "../.." }
|
iced = { path = "../..", features = ["debug"] }
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
///
|
///
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
|
@ -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),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
|
@ -1 +1,2 @@
|
|||||||
max_width=80
|
max_width=80
|
||||||
|
edition="2018"
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
)?;
|
)?;
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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();
|
||||||
|
@ -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>(
|
||||||
|
Loading…
Reference in New Issue
Block a user