Merge branch 'master' of https://github.com/hecrj/iced into wgpu_outdatedframe

This commit is contained in:
Billy Messenger 2021-07-22 12:37:39 -05:00
commit e822f654e4
219 changed files with 6266 additions and 1761 deletions

View file

@ -82,7 +82,12 @@ impl<'a> Layer<'a> {
let mut layers = vec![first_layer];
Self::process_primitive(&mut layers, Vector::new(0.0, 0.0), primitive);
Self::process_primitive(
&mut layers,
Vector::new(0.0, 0.0),
primitive,
0,
);
layers
}
@ -91,13 +96,19 @@ impl<'a> Layer<'a> {
layers: &mut Vec<Self>,
translation: Vector,
primitive: &'a Primitive,
current_layer: usize,
) {
match primitive {
Primitive::None => {}
Primitive::Group { primitives } => {
// TODO: Inspect a bit and regroup (?)
for primitive in primitives {
Self::process_primitive(layers, translation, primitive)
Self::process_primitive(
layers,
translation,
primitive,
current_layer,
)
}
}
Primitive::Text {
@ -109,7 +120,7 @@ impl<'a> Layer<'a> {
horizontal_alignment,
vertical_alignment,
} => {
let layer = layers.last_mut().unwrap();
let layer = &mut layers[current_layer];
layer.text.push(Text {
content,
@ -128,7 +139,7 @@ impl<'a> Layer<'a> {
border_width,
border_color,
} => {
let layer = layers.last_mut().unwrap();
let layer = &mut layers[current_layer];
// TODO: Move some of these computations to the GPU (?)
layer.quads.push(Quad {
@ -146,7 +157,7 @@ impl<'a> Layer<'a> {
});
}
Primitive::Mesh2D { buffers, size } => {
let layer = layers.last_mut().unwrap();
let layer = &mut layers[current_layer];
let bounds = Rectangle::new(
Point::new(translation.x, translation.y),
@ -167,7 +178,7 @@ impl<'a> Layer<'a> {
offset,
content,
} => {
let layer = layers.last_mut().unwrap();
let layer = &mut layers[current_layer];
let translated_bounds = *bounds + translation;
// Only draw visible content
@ -175,16 +186,15 @@ impl<'a> Layer<'a> {
layer.bounds.intersection(&translated_bounds)
{
let clip_layer = Layer::new(clip_bounds);
let new_layer = Layer::new(layer.bounds);
layers.push(clip_layer);
Self::process_primitive(
layers,
translation
- Vector::new(offset.x as f32, offset.y as f32),
content,
layers.len() - 1,
);
layers.push(new_layer);
}
}
Primitive::Translate {
@ -195,13 +205,19 @@ impl<'a> Layer<'a> {
layers,
translation + *new_translation,
&content,
current_layer,
);
}
Primitive::Cached { cache } => {
Self::process_primitive(layers, translation, &cache);
Self::process_primitive(
layers,
translation,
&cache,
current_layer,
);
}
Primitive::Image { handle, bounds } => {
let layer = layers.last_mut().unwrap();
let layer = &mut layers[current_layer];
layer.images.push(Image::Raster {
handle: handle.clone(),
@ -209,7 +225,7 @@ impl<'a> Layer<'a> {
});
}
Primitive::Svg { handle, bounds } => {
let layer = layers.last_mut().unwrap();
let layer = &mut layers[current_layer];
layer.images.push(Image::Vector {
handle: handle.clone(),

View file

@ -2,8 +2,8 @@
use crate::backend::{self, Backend};
use crate::{Primitive, Renderer};
use iced_native::{
mouse, overlay, Color, Font, HorizontalAlignment, Point, Rectangle,
VerticalAlignment,
mouse, overlay, Color, Font, HorizontalAlignment, Padding, Point,
Rectangle, VerticalAlignment,
};
pub use iced_style::menu::Style;
@ -45,7 +45,7 @@ where
viewport: &Rectangle,
options: &[T],
hovered_option: Option<usize>,
padding: u16,
padding: Padding,
text_size: u16,
font: Font,
style: &Style,
@ -53,7 +53,7 @@ where
use std::f32;
let is_mouse_over = bounds.contains(cursor_position);
let option_height = text_size as usize + padding as usize * 2;
let option_height = (text_size + padding.vertical()) as usize;
let mut primitives = Vec::new();
@ -72,7 +72,7 @@ where
x: bounds.x,
y: bounds.y + (option_height * i) as f32,
width: bounds.width,
height: f32::from(text_size + padding * 2),
height: f32::from(text_size + padding.vertical()),
};
if is_selected {
@ -88,7 +88,7 @@ where
primitives.push(Primitive::Text {
content: option.to_string(),
bounds: Rectangle {
x: bounds.x + f32::from(padding),
x: bounds.x + padding.left as f32,
y: bounds.center_y(),
width: f32::INFINITY,
..bounds

View file

@ -31,7 +31,7 @@ impl Viewport {
/// Returns the physical width of the [`Viewport`].
pub fn physical_width(&self) -> u32 {
self.physical_size.height
self.physical_size.width
}
/// Returns the physical height of the [`Viewport`].

View file

@ -20,6 +20,8 @@ pub mod scrollable;
pub mod slider;
pub mod svg;
pub mod text_input;
pub mod toggler;
pub mod tooltip;
mod column;
mod row;
@ -48,6 +50,10 @@ pub use scrollable::Scrollable;
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;

View file

@ -5,7 +5,7 @@ use crate::defaults::{self, Defaults};
use crate::{Backend, Primitive, Renderer};
use iced_native::mouse;
use iced_native::{
Background, Color, Element, Layout, Point, Rectangle, Vector,
Background, Color, Element, Layout, Padding, Point, Rectangle, Vector,
};
pub use iced_native::button::State;
@ -21,7 +21,7 @@ impl<B> iced_native::button::Renderer for Renderer<B>
where
B: Backend,
{
const DEFAULT_PADDING: u16 = 5;
const DEFAULT_PADDING: Padding = Padding::new(5);
type Style = Box<dyn StyleSheet>;

View file

@ -154,9 +154,9 @@ where
event: iced_native::Event,
layout: Layout<'_>,
cursor_position: Point,
messages: &mut Vec<Message>,
_renderer: &Renderer<B>,
_clipboard: Option<&dyn Clipboard>,
_clipboard: &mut dyn Clipboard,
messages: &mut Vec<Message>,
) -> event::Status {
let bounds = layout.bounds();

View file

@ -54,7 +54,7 @@ impl Frame {
self.size.width
}
/// Returns the width of the [`Frame`].
/// Returns the height of the [`Frame`].
#[inline]
pub fn height(&self) -> f32 {
self.size.height

View file

@ -34,7 +34,7 @@ pub trait Program<Message> {
/// [`Geometry`] can be easily generated with a [`Frame`] or stored in a
/// [`Cache`].
///
/// [`Frame`]: crate::widget::canvas::Cache
/// [`Frame`]: crate::widget::canvas::Frame
/// [`Cache`]: crate::widget::canvas::Cache
fn draw(&self, bounds: Rectangle, cursor: Cursor) -> Vec<Geometry>;

View file

@ -1,11 +1,14 @@
//! Display images in your user interface.
pub mod viewer;
use crate::backend::{self, Backend};
use crate::{Primitive, Renderer};
use iced_native::image;
use iced_native::mouse;
use iced_native::Layout;
pub use iced_native::image::{Handle, Image};
pub use iced_native::image::{Handle, Image, Viewer};
impl<B> image::Renderer for Renderer<B>
where

View file

@ -0,0 +1,55 @@
//! Zoom and pan on an image.
use crate::backend::{self, Backend};
use crate::{Primitive, Renderer};
use iced_native::image;
use iced_native::image::viewer;
use iced_native::mouse;
use iced_native::{Rectangle, Size, Vector};
impl<B> viewer::Renderer for Renderer<B>
where
B: Backend + backend::Image,
{
fn draw(
&mut self,
state: &viewer::State,
bounds: Rectangle,
image_size: Size,
translation: Vector,
handle: image::Handle,
is_mouse_over: bool,
) -> Self::Output {
(
{
Primitive::Clip {
bounds,
content: Box::new(Primitive::Translate {
translation,
content: Box::new(Primitive::Image {
handle,
bounds: Rectangle {
x: bounds.x,
y: bounds.y,
..Rectangle::with_size(image_size)
},
}),
}),
offset: Vector::new(0, 0),
}
},
{
if state.is_cursor_grabbed() {
mouse::Interaction::Grabbing
} else if is_mouse_over
&& (image_size.width > bounds.width
|| image_size.height > bounds.height)
{
mouse::Interaction::Grab
} else {
mouse::Interaction::Idle
}
},
)
}
}

View file

@ -6,23 +6,21 @@
//! 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.2/examples/pane_grid
use crate::backend::{self, Backend};
//! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.3/examples/pane_grid
use crate::defaults;
use crate::{Primitive, Renderer};
use crate::{Backend, Color, Primitive, Renderer};
use iced_native::container;
use iced_native::mouse;
use iced_native::pane_grid;
use iced_native::text;
use iced_native::{
Element, HorizontalAlignment, Layout, Point, Rectangle, Vector,
VerticalAlignment,
};
use iced_native::{Element, Layout, Point, Rectangle, Vector};
pub use iced_native::pane_grid::{
Axis, Configuration, Content, Direction, DragEvent, Pane, ResizeEvent,
Split, State, TitleBar,
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.
///
@ -34,16 +32,20 @@ pub type PaneGrid<'a, Message, Backend> =
impl<B> pane_grid::Renderer for Renderer<B>
where
B: Backend + backend::Text,
B: Backend,
{
type Style = Box<dyn StyleSheet>;
fn draw<Message>(
&mut self,
defaults: &Self::Defaults,
content: &[(Pane, Content<'_, Message, Self>)],
dragging: Option<(Pane, Point)>,
resizing: Option<Axis>,
resizing: Option<(Axis, Rectangle, bool)>,
layout: Layout<'_>,
style_sheet: &<Self as pane_grid::Renderer>::Style,
cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output {
let pane_cursor_position = if dragging.is_some() {
// TODO: Remove once cursor availability is encoded in the type
@ -61,8 +63,13 @@ where
.zip(layout.children())
.enumerate()
.map(|(i, ((id, pane), layout))| {
let (primitive, new_mouse_interaction) =
pane.draw(self, defaults, layout, pane_cursor_position);
let (primitive, new_mouse_interaction) = pane.draw(
self,
defaults,
layout,
pane_cursor_position,
viewport,
);
if new_mouse_interaction > mouse_interaction {
mouse_interaction = new_mouse_interaction;
@ -78,7 +85,8 @@ where
})
.collect();
let primitives = if let Some((index, layout, origin)) = dragged_pane {
let mut primitives = if let Some((index, layout, origin)) = dragged_pane
{
let pane = panes.remove(index);
let bounds = layout.bounds();
@ -108,15 +116,62 @@ where
panes
};
let (primitives, mouse_interaction) =
if let Some((axis, split_region, is_picked)) = resizing {
let highlight = if is_picked {
style_sheet.picked_split()
} else {
style_sheet.hovered_split()
};
if let Some(highlight) = highlight {
primitives.push(Primitive::Quad {
bounds: match axis {
Axis::Horizontal => Rectangle {
x: split_region.x,
y: (split_region.y
+ (split_region.height - highlight.width)
/ 2.0)
.round(),
width: split_region.width,
height: highlight.width,
},
Axis::Vertical => Rectangle {
x: (split_region.x
+ (split_region.width - highlight.width)
/ 2.0)
.round(),
y: split_region.y,
width: highlight.width,
height: split_region.height,
},
},
background: highlight.color.into(),
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
});
}
(
primitives,
match axis {
Axis::Horizontal => {
mouse::Interaction::ResizingVertically
}
Axis::Vertical => {
mouse::Interaction::ResizingHorizontally
}
},
)
} else {
(primitives, mouse_interaction)
};
(
Primitive::Group { primitives },
if dragging.is_some() {
mouse::Interaction::Grabbing
} else if let Some(axis) = resizing {
match axis {
Axis::Horizontal => mouse::Interaction::ResizingVertically,
Axis::Vertical => mouse::Interaction::ResizingHorizontally,
}
} else {
mouse_interaction
},
@ -127,16 +182,17 @@ where
&mut self,
defaults: &Self::Defaults,
bounds: Rectangle,
style_sheet: &Self::Style,
style_sheet: &<Self as container::Renderer>::Style,
title_bar: Option<(&TitleBar<'_, Message, Self>, Layout<'_>)>,
body: (&Element<'_, Message, Self>, Layout<'_>),
cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output {
let style = style_sheet.style();
let (body, body_layout) = body;
let (body_primitive, body_interaction) =
body.draw(self, defaults, body_layout, cursor_position, &bounds);
body.draw(self, defaults, body_layout, cursor_position, viewport);
let background = crate::widget::container::background(bounds, &style);
@ -150,6 +206,7 @@ where
defaults,
title_bar_layout,
cursor_position,
viewport,
show_controls,
);
@ -161,10 +218,10 @@ where
body_primitive,
],
},
if is_over_pick_area {
mouse::Interaction::Grab
} else if title_bar_interaction > body_interaction {
if title_bar_interaction > body_interaction {
title_bar_interaction
} else if is_over_pick_area {
mouse::Interaction::Grab
} else {
body_interaction
},
@ -187,15 +244,14 @@ where
&mut self,
defaults: &Self::Defaults,
bounds: Rectangle,
style_sheet: &Self::Style,
title: &str,
title_size: u16,
title_font: Self::Font,
title_bounds: Rectangle,
style_sheet: &<Self as container::Renderer>::Style,
content: (&Element<'_, Message, Self>, Layout<'_>),
controls: Option<(&Element<'_, Message, Self>, Layout<'_>)>,
cursor_position: Point,
viewport: &Rectangle,
) -> Self::Output {
let style = style_sheet.style();
let (title_content, title_layout) = content;
let defaults = Self::Defaults {
text: defaults::Text {
@ -205,16 +261,12 @@ where
let background = crate::widget::container::background(bounds, &style);
let (title_primitive, _) = text::Renderer::draw(
let (title_primitive, title_interaction) = title_content.draw(
self,
&defaults,
title_bounds,
title,
title_size,
title_font,
None,
HorizontalAlignment::Left,
VerticalAlignment::Top,
title_layout,
cursor_position,
viewport,
);
if let Some((controls, controls_layout)) = controls {
@ -223,7 +275,7 @@ where
&defaults,
controls_layout,
cursor_position,
&bounds,
viewport,
);
(
@ -234,7 +286,7 @@ where
controls_primitive,
],
},
controls_interaction,
controls_interaction.max(title_interaction),
)
} else {
(
@ -245,7 +297,7 @@ where
} else {
title_primitive
},
mouse::Interaction::default(),
title_interaction,
)
}
}

View file

@ -2,7 +2,8 @@
use crate::backend::{self, Backend};
use crate::{Primitive, Renderer};
use iced_native::{
mouse, Font, HorizontalAlignment, Point, Rectangle, VerticalAlignment,
mouse, Font, HorizontalAlignment, Padding, Point, Rectangle,
VerticalAlignment,
};
use iced_style::menu;
@ -19,7 +20,7 @@ where
{
type Style = Box<dyn StyleSheet>;
const DEFAULT_PADDING: u16 = 5;
const DEFAULT_PADDING: Padding = Padding::new(5);
fn menu_style(style: &Box<dyn StyleSheet>) -> menu::Style {
style.menu()
@ -30,12 +31,14 @@ where
bounds: Rectangle,
cursor_position: Point,
selected: Option<String>,
padding: u16,
placeholder: Option<&str>,
padding: Padding,
text_size: u16,
font: Font,
style: &Box<dyn StyleSheet>,
) -> Self::Output {
let is_mouse_over = bounds.contains(cursor_position);
let is_selected = selected.is_some();
let style = if is_mouse_over {
style.hovered()
@ -56,7 +59,7 @@ where
font: B::ICON_FONT,
size: bounds.height * style.icon_size,
bounds: Rectangle {
x: bounds.x + bounds.width - f32::from(padding) * 2.0,
x: bounds.x + bounds.width - f32::from(padding.horizontal()),
y: bounds.center_y(),
..bounds
},
@ -67,14 +70,18 @@ where
(
Primitive::Group {
primitives: if let Some(label) = selected {
primitives: if let Some(label) =
selected.or_else(|| placeholder.map(str::to_string))
{
let label = Primitive::Text {
content: label,
size: f32::from(text_size),
font,
color: style.text_color,
color: is_selected
.then(|| style.text_color)
.unwrap_or(style.placeholder_color),
bounds: Rectangle {
x: bounds.x + f32::from(padding),
x: bounds.x + f32::from(padding.left),
y: bounds.center_y(),
..bounds
},

View file

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

View file

@ -0,0 +1,99 @@
//! Show toggle controls using togglers.
use crate::backend::{self, Backend};
use crate::{Primitive, Renderer};
use iced_native::mouse;
use iced_native::toggler;
use iced_native::Rectangle;
pub use iced_style::toggler::{Style, StyleSheet};
/// Makes sure that the border radius of the toggler looks good at every size.
const BORDER_RADIUS_RATIO: f32 = 32.0 / 13.0;
/// The space ratio between the background Quad and the Toggler bounds, and
/// between the background Quad and foreground Quad.
const SPACE_RATIO: f32 = 0.05;
/// A toggler that can be toggled.
///
/// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`.
pub type Toggler<Message, Backend> =
iced_native::Toggler<Message, Renderer<Backend>>;
impl<B> toggler::Renderer for Renderer<B>
where
B: Backend + backend::Text,
{
type Style = Box<dyn StyleSheet>;
const DEFAULT_SIZE: u16 = 20;
fn draw(
&mut self,
bounds: Rectangle,
is_active: bool,
is_mouse_over: bool,
label: Option<Self::Output>,
style_sheet: &Self::Style,
) -> Self::Output {
let style = if is_mouse_over {
style_sheet.hovered(is_active)
} else {
style_sheet.active(is_active)
};
let border_radius = bounds.height as f32 / BORDER_RADIUS_RATIO;
let space = SPACE_RATIO * bounds.height as f32;
let toggler_background_bounds = Rectangle {
x: bounds.x + space,
y: bounds.y + space,
width: bounds.width - (2.0 * space),
height: bounds.height - (2.0 * space),
};
let toggler_background = Primitive::Quad {
bounds: toggler_background_bounds,
background: style.background.into(),
border_radius,
border_width: 1.0,
border_color: style.background_border.unwrap_or(style.background),
};
let toggler_foreground_bounds = Rectangle {
x: bounds.x
+ if is_active {
bounds.width - 2.0 * space - (bounds.height - (4.0 * space))
} else {
2.0 * space
},
y: bounds.y + (2.0 * space),
width: bounds.height - (4.0 * space),
height: bounds.height - (4.0 * space),
};
let toggler_foreground = Primitive::Quad {
bounds: toggler_foreground_bounds,
background: style.foreground.into(),
border_radius,
border_width: 1.0,
border_color: style.foreground_border.unwrap_or(style.foreground),
};
(
Primitive::Group {
primitives: match label {
Some((l, _)) => {
vec![l, toggler_background, toggler_foreground]
}
None => vec![toggler_background, toggler_foreground],
},
},
if is_mouse_over {
mouse::Interaction::Pointer
} else {
mouse::Interaction::default()
},
)
}
}

View file

@ -0,0 +1,168 @@
//! Decorate content and apply alignment.
use crate::backend::{self, Backend};
use crate::defaults::{self, Defaults};
use crate::{Primitive, Renderer, Vector};
use iced_native::container;
use iced_native::layout::{self, Layout};
use iced_native::{Element, Padding, Point, Rectangle, Size, Text};
/// 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::Tooltip<'a, Message, Renderer<Backend>>;
pub use iced_native::tooltip::Position;
impl<B> iced_native::tooltip::Renderer for Renderer<B>
where
B: Backend + backend::Text,
{
const DEFAULT_PADDING: u16 = 5;
fn draw<Message>(
&mut self,
defaults: &Defaults,
cursor_position: Point,
content_layout: Layout<'_>,
viewport: &Rectangle,
content: &Element<'_, Message, Self>,
tooltip: &Text<Self>,
position: Position,
style_sheet: &<Self as container::Renderer>::Style,
gap: u16,
padding: u16,
) -> Self::Output {
let (content, mouse_interaction) = content.draw(
self,
&defaults,
content_layout,
cursor_position,
viewport,
);
let bounds = content_layout.bounds();
if bounds.contains(cursor_position) {
use iced_native::Widget;
let gap = f32::from(gap);
let style = style_sheet.style();
let defaults = Defaults {
text: defaults::Text {
color: style.text_color.unwrap_or(defaults.text.color),
},
};
let text_layout = Widget::<(), Self>::layout(
tooltip,
self,
&layout::Limits::new(Size::ZERO, viewport.size())
.pad(Padding::new(padding)),
);
let padding = f32::from(padding);
let text_bounds = text_layout.bounds();
let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0;
let y_center =
bounds.y + (bounds.height - text_bounds.height) / 2.0;
let mut tooltip_bounds = {
let offset = match position {
Position::Top => Vector::new(
x_center,
bounds.y - text_bounds.height - gap - padding,
),
Position::Bottom => Vector::new(
x_center,
bounds.y + bounds.height + gap + padding,
),
Position::Left => Vector::new(
bounds.x - text_bounds.width - gap - padding,
y_center,
),
Position::Right => Vector::new(
bounds.x + bounds.width + gap + padding,
y_center,
),
Position::FollowCursor => Vector::new(
cursor_position.x,
cursor_position.y - text_bounds.height,
),
};
Rectangle {
x: offset.x - padding,
y: offset.y - padding,
width: text_bounds.width + padding * 2.0,
height: text_bounds.height + padding * 2.0,
}
};
if tooltip_bounds.x < viewport.x {
tooltip_bounds.x = viewport.x;
} else if viewport.x + viewport.width
< tooltip_bounds.x + tooltip_bounds.width
{
tooltip_bounds.x =
viewport.x + viewport.width - tooltip_bounds.width;
}
if tooltip_bounds.y < viewport.y {
tooltip_bounds.y = viewport.y;
} else if viewport.y + viewport.height
< tooltip_bounds.y + tooltip_bounds.height
{
tooltip_bounds.y =
viewport.y + viewport.height - tooltip_bounds.height;
}
let (tooltip, _) = Widget::<(), Self>::draw(
tooltip,
self,
&defaults,
Layout::with_offset(
Vector::new(
tooltip_bounds.x + padding,
tooltip_bounds.y + padding,
),
&text_layout,
),
cursor_position,
viewport,
);
(
Primitive::Group {
primitives: vec![
content,
Primitive::Clip {
bounds: *viewport,
offset: Vector::new(0, 0),
content: Box::new(
if let Some(background) =
crate::container::background(
tooltip_bounds,
&style,
)
{
Primitive::Group {
primitives: vec![background, tooltip],
}
} else {
tooltip
},
),
},
],
},
mouse_interaction,
)
} else {
(content, mouse_interaction)
}
}
}

View file

@ -17,7 +17,10 @@ pub trait Compositor: Sized {
type SwapChain;
/// 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.
///