summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-05-21 00:37:47 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-05-21 00:44:35 +0200
commite0e4ee73feead3f05730625c7e1917b63f0b384e (patch)
tree5cd934cc474a5aacc60359f6fe69a5b9d31fe45b
parenta1a5fcfd46622d5b18d1716aa2adb4659835ccf3 (diff)
downloadiced-e0e4ee73feead3f05730625c7e1917b63f0b384e.tar.gz
iced-e0e4ee73feead3f05730625c7e1917b63f0b384e.tar.bz2
iced-e0e4ee73feead3f05730625c7e1917b63f0b384e.zip
Implement `iced_glutin` :tada:
-rw-r--r--Cargo.toml13
-rw-r--r--examples/custom_widget/Cargo.toml2
-rw-r--r--examples/custom_widget/src/main.rs18
-rw-r--r--examples/geometry/Cargo.toml2
-rw-r--r--examples/geometry/src/main.rs24
-rw-r--r--examples/todos/Cargo.toml2
-rw-r--r--examples/tour/Cargo.toml3
-rw-r--r--examples/tour/src/main.rs40
-rw-r--r--glow/Cargo.toml13
-rw-r--r--glow/src/backend.rs29
-rw-r--r--glow/src/widget.rs11
-rw-r--r--glow/src/widget/canvas.rs194
-rw-r--r--glow/src/window/compositor.rs170
-rw-r--r--glutin/Cargo.toml30
-rw-r--r--glutin/README.md27
-rw-r--r--glutin/src/application.rs429
-rw-r--r--glutin/src/lib.rs15
-rw-r--r--graphics/Cargo.toml1
-rw-r--r--graphics/src/layer.rs1
-rw-r--r--graphics/src/window.rs6
-rw-r--r--graphics/src/window/gl_compositor.rs24
-rw-r--r--src/application.rs20
-rw-r--r--src/element.rs2
-rw-r--r--src/lib.rs2
-rw-r--r--src/settings.rs8
-rw-r--r--src/widget.rs24
-rw-r--r--winit/src/application.rs32
-rw-r--r--winit/src/lib.rs7
-rw-r--r--winit/src/proxy.rs1
-rw-r--r--winit/src/settings.rs36
-rw-r--r--winit/src/size.rs30
31 files changed, 718 insertions, 498 deletions
diff --git a/Cargo.toml b/Cargo.toml
index aa6216cf..9339f4ed 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,13 +13,13 @@ categories = ["gui"]
[features]
# Enables the `Image` widget
-image = ["iced_wgpu/image"]
+image = ["iced_glow/image"]
# Enables the `Svg` widget
-svg = ["iced_wgpu/svg"]
+svg = ["iced_glow/svg"]
# Enables the `Canvas` widget
-canvas = ["iced_wgpu/canvas"]
+canvas = ["iced_glow/canvas"]
# Enables a debug view in native platforms (press F12)
-debug = ["iced_winit/debug"]
+debug = ["iced_glutin/debug"]
# Enables `tokio` as the `executor::Default` on native platforms
tokio = ["iced_futures/tokio"]
# Enables `async-std` as the `executor::Default` on native platforms
@@ -36,6 +36,7 @@ members = [
"futures",
"graphics",
"glow",
+ "glutin",
"native",
"style",
"web",
@@ -67,8 +68,8 @@ iced_core = { version = "0.2", path = "core" }
iced_futures = { version = "0.1", path = "futures" }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
-iced_winit = { version = "0.1", path = "winit" }
-iced_wgpu = { version = "0.2", path = "wgpu" }
+iced_glutin = { version = "0.1", path = "glutin" }
+iced_glow = { version = "0.1", path = "glow" }
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced_web = { version = "0.2", path = "web" }
diff --git a/examples/custom_widget/Cargo.toml b/examples/custom_widget/Cargo.toml
index 30747dc0..3942538d 100644
--- a/examples/custom_widget/Cargo.toml
+++ b/examples/custom_widget/Cargo.toml
@@ -8,4 +8,4 @@ publish = false
[dependencies]
iced = { path = "../.." }
iced_native = { path = "../../native" }
-iced_wgpu = { path = "../../wgpu" }
+iced_graphics = { path = "../../graphics" }
diff --git a/examples/custom_widget/src/main.rs b/examples/custom_widget/src/main.rs
index f096fb54..bcf896b0 100644
--- a/examples/custom_widget/src/main.rs
+++ b/examples/custom_widget/src/main.rs
@@ -9,11 +9,11 @@ mod circle {
// Of course, you can choose to make the implementation renderer-agnostic,
// if you wish to, by creating your own `Renderer` trait, which could be
// implemented by `iced_wgpu` and other renderers.
+ use iced_graphics::{Backend, Defaults, Primitive, Renderer};
use iced_native::{
layout, mouse, Background, Color, Element, Hasher, Layout, Length,
Point, Size, Widget,
};
- use iced_wgpu::{Defaults, Primitive, Renderer};
pub struct Circle {
radius: u16,
@@ -25,7 +25,10 @@ mod circle {
}
}
- impl<Message> Widget<Message, Renderer> for Circle {
+ impl<Message, B> Widget<Message, Renderer<B>> for Circle
+ where
+ B: Backend,
+ {
fn width(&self) -> Length {
Length::Shrink
}
@@ -36,7 +39,7 @@ mod circle {
fn layout(
&self,
- _renderer: &Renderer,
+ _renderer: &Renderer<B>,
_limits: &layout::Limits,
) -> layout::Node {
layout::Node::new(Size::new(
@@ -53,7 +56,7 @@ mod circle {
fn draw(
&self,
- _renderer: &mut Renderer,
+ _renderer: &mut Renderer<B>,
_defaults: &Defaults,
layout: Layout<'_>,
_cursor_position: Point,
@@ -71,8 +74,11 @@ mod circle {
}
}
- impl<'a, Message> Into<Element<'a, Message, Renderer>> for Circle {
- fn into(self) -> Element<'a, Message, Renderer> {
+ impl<'a, Message, B> Into<Element<'a, Message, Renderer<B>>> for Circle
+ where
+ B: Backend,
+ {
+ fn into(self) -> Element<'a, Message, Renderer<B>> {
Element::new(self)
}
}
diff --git a/examples/geometry/Cargo.toml b/examples/geometry/Cargo.toml
index 9df52454..34eec4fb 100644
--- a/examples/geometry/Cargo.toml
+++ b/examples/geometry/Cargo.toml
@@ -8,4 +8,4 @@ publish = false
[dependencies]
iced = { path = "../.." }
iced_native = { path = "../../native" }
-iced_wgpu = { path = "../../wgpu" }
+iced_graphics = { path = "../../graphics" }
diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs
index aabe6b21..71ce0d8c 100644
--- a/examples/geometry/src/main.rs
+++ b/examples/geometry/src/main.rs
@@ -10,14 +10,14 @@ mod rainbow {
// Of course, you can choose to make the implementation renderer-agnostic,
// if you wish to, by creating your own `Renderer` trait, which could be
// implemented by `iced_wgpu` and other renderers.
+ use iced_graphics::{
+ triangle::{Mesh2D, Vertex2D},
+ Backend, Defaults, Primitive, Renderer,
+ };
use iced_native::{
layout, mouse, Element, Hasher, Layout, Length, Point, Size, Vector,
Widget,
};
- use iced_wgpu::{
- triangle::{Mesh2D, Vertex2D},
- Defaults, Primitive, Renderer,
- };
pub struct Rainbow;
@@ -27,7 +27,10 @@ mod rainbow {
}
}
- impl<Message> Widget<Message, Renderer> for Rainbow {
+ impl<Message, B> Widget<Message, Renderer<B>> for Rainbow
+ where
+ B: Backend,
+ {
fn width(&self) -> Length {
Length::Fill
}
@@ -38,7 +41,7 @@ mod rainbow {
fn layout(
&self,
- _renderer: &Renderer,
+ _renderer: &Renderer<B>,
limits: &layout::Limits,
) -> layout::Node {
let size = limits.width(Length::Fill).resolve(Size::ZERO);
@@ -50,7 +53,7 @@ mod rainbow {
fn draw(
&self,
- _renderer: &mut Renderer,
+ _renderer: &mut Renderer<B>,
_defaults: &Defaults,
layout: Layout<'_>,
cursor_position: Point,
@@ -146,8 +149,11 @@ mod rainbow {
}
}
- impl<'a, Message> Into<Element<'a, Message, Renderer>> for Rainbow {
- fn into(self) -> Element<'a, Message, Renderer> {
+ impl<'a, Message, B> Into<Element<'a, Message, Renderer<B>>> for Rainbow
+ where
+ B: Backend,
+ {
+ fn into(self) -> Element<'a, Message, Renderer<B>> {
Element::new(self)
}
}
diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml
index f945cde5..b236cc0d 100644
--- a/examples/todos/Cargo.toml
+++ b/examples/todos/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2018"
publish = false
[dependencies]
-iced = { path = "../..", features = ["async-std"] }
+iced = { path = "../..", features = ["async-std", "debug"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
diff --git a/examples/tour/Cargo.toml b/examples/tour/Cargo.toml
index b34c5feb..96749e90 100644
--- a/examples/tour/Cargo.toml
+++ b/examples/tour/Cargo.toml
@@ -6,6 +6,5 @@ edition = "2018"
publish = false
[dependencies]
-iced_winit = { path = "../../winit", features = ["debug"] }
-iced_glow = { path = "../../glow" }
+iced = { path = "../..", features = ["image", "debug"] }
env_logger = "0.7"
diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs
index 8c3b1d19..ca7a4f5d 100644
--- a/examples/tour/src/main.rs
+++ b/examples/tour/src/main.rs
@@ -1,20 +1,14 @@
-use iced_glow::{
- button, scrollable, slider, text_input, window, Button, Checkbox, Color,
- Column, Command, Container, Element, HorizontalAlignment, Image, Length,
- Radio, Row, Scrollable, Slider, Space, Text, TextInput,
+use iced::{
+ button, executor, scrollable, slider, text_input, Application, Button,
+ Checkbox, Color, Column, Command, Container, Element, HorizontalAlignment,
+ Image, Length, Radio, Row, Scrollable, Settings, Slider, Space, Text,
+ TextInput,
};
-use iced_winit::{executor, Application, Settings};
pub fn main() {
env_logger::init();
- Tour::run(
- Settings::default(),
- iced_glow::Settings {
- default_font: None,
- antialiasing: None,
- },
- )
+ Tour::run(Settings::default())
}
pub struct Tour {
@@ -26,7 +20,6 @@ pub struct Tour {
}
impl Application for Tour {
- type Compositor = window::Compositor;
type Executor = executor::Null;
type Message = Message;
type Flags = ();
@@ -693,18 +686,17 @@ impl<'a> Step {
fn ferris<'a>(width: u16) -> Container<'a, StepMessage> {
Container::new(
- Text::new("Not supported yet!")
// This should go away once we unify resource loading on native
// platforms
- //if cfg!(target_arch = "wasm32") {
- // Image::new("images/ferris.png")
- //} else {
- // Image::new(format!(
- // "{}/images/ferris.png",
- // env!("CARGO_MANIFEST_DIR")
- // ))
- //}
- //.width(Length::Units(width)),
+ if cfg!(target_arch = "wasm32") {
+ Image::new("images/ferris.png")
+ } else {
+ Image::new(format!(
+ "{}/images/ferris.png",
+ env!("CARGO_MANIFEST_DIR")
+ ))
+ }
+ .width(Length::Units(width)),
)
.width(Length::Fill)
.center_x()
@@ -765,7 +757,7 @@ pub enum Layout {
}
mod style {
- use iced_glow::{button, Background, Color, Vector};
+ use iced::{button, Background, Color, Vector};
pub enum Button {
Primary,
diff --git a/glow/Cargo.toml b/glow/Cargo.toml
index 72ed8758..148f4fd5 100644
--- a/glow/Cargo.toml
+++ b/glow/Cargo.toml
@@ -7,8 +7,12 @@ description = "A glow renderer for iced"
license = "MIT AND OFL-1.1"
repository = "https://github.com/hecrj/iced"
+[features]
+canvas = ["iced_graphics/canvas"]
+image = []
+svg = []
+
[dependencies]
-raw-window-handle = "0.3"
euclid = "0.20"
glow = "0.4"
bytemuck = "1.2"
@@ -23,12 +27,7 @@ path = "../native"
[dependencies.iced_graphics]
version = "0.1"
path = "../graphics"
-features = ["font-source", "font-fallback", "font-icons"]
-
-[dependencies.surfman]
-path = "../../surfman/surfman"
-default-features = false
-features = ["sm-raw-window-handle", "sm-x11"]
+features = ["font-source", "font-fallback", "font-icons", "opengl"]
[dependencies.glow_glyph]
path = "../../glow_glyph"
diff --git a/glow/src/backend.rs b/glow/src/backend.rs
index 5e2aa837..8c578d5e 100644
--- a/glow/src/backend.rs
+++ b/glow/src/backend.rs
@@ -36,12 +36,6 @@ impl Backend {
}
}
- /// Draws the provided primitives in the given [`Target`].
- ///
- /// The text provided as overlay will be renderer on top of the primitives.
- /// This is useful for rendering debug information.
- ///
- /// [`Target`]: struct.Target.html
pub fn draw<T: AsRef<str>>(
&mut self,
gl: &glow::Context,
@@ -50,6 +44,7 @@ impl Backend {
overlay_text: &[T],
) -> mouse::Interaction {
let viewport_size = viewport.physical_size();
+ let scale_factor = viewport.scale_factor() as f32;
let projection = viewport.projection();
let mut layers = Layer::generate(primitive, viewport);
@@ -58,7 +53,7 @@ impl Backend {
for layer in layers {
self.flush(
gl,
- viewport.scale_factor() as f32,
+ scale_factor,
projection,
&layer,
viewport_size.width,
@@ -78,7 +73,8 @@ impl Backend {
target_width: u32,
target_height: u32,
) {
- let bounds = (layer.bounds * scale_factor).round();
+ let mut bounds = (layer.bounds * scale_factor).round();
+ bounds.height = bounds.height.min(target_height);
if !layer.quads.is_empty() {
self.quad_pipeline.draw(
@@ -204,3 +200,20 @@ impl backend::Text for Backend {
self.text_pipeline.space_width(size)
}
}
+
+#[cfg(feature = "image")]
+impl backend::Image for Backend {
+ fn dimensions(&self, _handle: &iced_native::image::Handle) -> (u32, u32) {
+ (50, 50)
+ }
+}
+
+#[cfg(feature = "svg")]
+impl backend::Svg for Backend {
+ fn viewport_dimensions(
+ &self,
+ _handle: &iced_native::svg::Handle,
+ ) -> (u32, u32) {
+ (50, 50)
+ }
+}
diff --git a/glow/src/widget.rs b/glow/src/widget.rs
index 16e7ca88..362465f4 100644
--- a/glow/src/widget.rs
+++ b/glow/src/widget.rs
@@ -38,7 +38,16 @@ pub use slider::Slider;
#[doc(no_inline)]
pub use text_input::TextInput;
-pub use iced_native::{Image, Space, Text};
+#[cfg(feature = "canvas")]
+#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))]
+pub mod canvas;
+
+#[cfg(feature = "canvas")]
+#[doc(no_inline)]
+pub use canvas::Canvas;
+
+pub use iced_native::{Image, Space};
pub type Column<'a, Message> = iced_native::Column<'a, Message, Renderer>;
pub type Row<'a, Message> = iced_native::Row<'a, Message, Renderer>;
+pub type Text = iced_native::Text<Renderer>;
diff --git a/glow/src/widget/canvas.rs b/glow/src/widget/canvas.rs
index 325f90ce..bef34857 100644
--- a/glow/src/widget/canvas.rs
+++ b/glow/src/widget/canvas.rs
@@ -6,196 +6,4 @@
//!
//! [`Canvas`]: struct.Canvas.html
//! [`Frame`]: struct.Frame.html
-use crate::{Defaults, Primitive, Renderer};
-
-use iced_native::{
- layout, Element, Hasher, Layout, Length, MouseCursor, Point, Size, Widget,
-};
-use std::hash::Hash;
-
-pub mod layer;
-pub mod path;
-
-mod drawable;
-mod fill;
-mod frame;
-mod stroke;
-mod text;
-
-pub use drawable::Drawable;
-pub use fill::Fill;
-pub use frame::Frame;
-pub use layer::Layer;
-pub use path::Path;
-pub use stroke::{LineCap, LineJoin, Stroke};
-pub use text::Text;
-
-/// A widget capable of drawing 2D graphics.
-///
-/// A [`Canvas`] may contain multiple layers. A [`Layer`] is drawn using the
-/// painter's algorithm. In other words, layers will be drawn on top of each
-/// other in the same order they are pushed into the [`Canvas`].
-///
-/// [`Canvas`]: struct.Canvas.html
-/// [`Layer`]: layer/trait.Layer.html
-///
-/// # Examples
-/// The repository has a couple of [examples] showcasing how to use a
-/// [`Canvas`]:
-///
-/// - [`clock`], an application that uses the [`Canvas`] widget to draw a clock
-/// and its hands to display the current time.
-/// - [`solar_system`], an animated solar system drawn using the [`Canvas`] widget
-/// and showcasing how to compose different transforms.
-///
-/// [examples]: https://github.com/hecrj/iced/tree/0.1/examples
-/// [`clock`]: https://github.com/hecrj/iced/tree/0.1/examples/clock
-/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.1/examples/solar_system
-///
-/// ## 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 use iced_wgpu::canvas;
-/// # pub use iced_native::Color;
-/// # }
-/// use iced::canvas::{self, layer, Canvas, Drawable, Fill, Frame, Path};
-/// use iced::Color;
-///
-/// // First, we define the data we need for drawing
-/// #[derive(Debug)]
-/// struct Circle {
-/// radius: f32,
-/// }
-///
-/// // Then, we implement the `Drawable` trait
-/// impl Drawable for Circle {
-/// fn draw(&self, frame: &mut Frame) {
-/// // We create a `Path` representing a simple circle
-/// let circle = Path::new(|p| p.circle(frame.center(), self.radius));
-///
-/// // And fill it with some color
-/// frame.fill(&circle, Fill::Color(Color::BLACK));
-/// }
-/// }
-///
-/// // We can use a `Cache` to avoid unnecessary re-tessellation
-/// let cache: layer::Cache<Circle> = layer::Cache::new();
-///
-/// // Finally, we simply provide the data to our `Cache` and push the resulting
-/// // layer into a `Canvas`
-/// let canvas = Canvas::new()
-/// .push(cache.with(&Circle { radius: 50.0 }));
-/// ```
-#[derive(Debug)]
-pub struct Canvas<'a> {
- width: Length,
- height: Length,
- layers: Vec<Box<dyn Layer + 'a>>,
-}
-
-impl<'a> Canvas<'a> {
- const DEFAULT_SIZE: u16 = 100;
-
- /// Creates a new [`Canvas`] with no layers.
- ///
- /// [`Canvas`]: struct.Canvas.html
- pub fn new() -> Self {
- Canvas {
- width: Length::Units(Self::DEFAULT_SIZE),
- height: Length::Units(Self::DEFAULT_SIZE),
- layers: Vec::new(),
- }
- }
-
- /// Sets the width of the [`Canvas`].
- ///
- /// [`Canvas`]: struct.Canvas.html
- pub fn width(mut self, width: Length) -> Self {
- self.width = width;
- self
- }
-
- /// Sets the height of the [`Canvas`].
- ///
- /// [`Canvas`]: struct.Canvas.html
- pub fn height(mut self, height: Length) -> Self {
- self.height = height;
- self
- }
-
- /// Adds a [`Layer`] to the [`Canvas`].
- ///
- /// It will be drawn on top of previous layers.
- ///
- /// [`Layer`]: layer/trait.Layer.html
- /// [`Canvas`]: struct.Canvas.html
- pub fn push(mut self, layer: impl Layer + 'a) -> Self {
- self.layers.push(Box::new(layer));
- self
- }
-}
-
-impl<'a, Message> Widget<Message, Renderer> for Canvas<'a> {
- fn width(&self) -> Length {
- self.width
- }
-
- fn height(&self) -> Length {
- self.height
- }
-
- fn layout(
- &self,
- _renderer: &Renderer,
- 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 draw(
- &self,
- _renderer: &mut Renderer,
- _defaults: &Defaults,
- layout: Layout<'_>,
- _cursor_position: Point,
- ) -> (Primitive, MouseCursor) {
- let bounds = layout.bounds();
- let origin = Point::new(bounds.x, bounds.y);
- let size = Size::new(bounds.width, bounds.height);
-
- (
- Primitive::Group {
- primitives: self
- .layers
- .iter()
- .map(|layer| Primitive::Cached {
- origin,
- cache: layer.draw(size),
- })
- .collect(),
- },
- MouseCursor::Idle,
- )
- }
-
- fn hash_layout(&self, state: &mut Hasher) {
- std::any::TypeId::of::<Canvas<'static>>().hash(state);
-
- self.width.hash(state);
- self.height.hash(state);
- }
-}
-
-impl<'a, Message> From<Canvas<'a>> for Element<'a, Message, Renderer>
-where
- Message: 'static,
-{
- fn from(canvas: Canvas<'a>) -> Element<'a, Message, Renderer> {
- Element::new(canvas)
- }
-}
+pub use iced_graphics::canvas::*;
diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs
index 514904a8..1117166f 100644
--- a/glow/src/window/compositor.rs
+++ b/glow/src/window/compositor.rs
@@ -1,180 +1,64 @@
-use crate::{Renderer, Settings, Viewport};
+use crate::{Backend, Renderer, Settings, Viewport};
+use core::ffi::c_void;
use glow::HasContext;
+use iced_graphics::Size;
use iced_native::mouse;
-use raw_window_handle::HasRawWindowHandle;
/// A window graphics backend for iced powered by `glow`.
#[allow(missing_debug_implementations)]
pub struct Compositor {
- connection: surfman::Connection,
- device: surfman::Device,
- gl_context: surfman::Context,
- gl: Option<glow::Context>,
+ gl: glow::Context,
}
-impl iced_graphics::window::Compositor for Compositor {
+impl iced_graphics::window::GLCompositor for Compositor {
type Settings = Settings;
type Renderer = Renderer;
- type Surface = ();
- type SwapChain = ();
- fn new(_settings: Self::Settings) -> Self {
- let connection = surfman::Connection::new().expect("Create connection");
+ unsafe fn new(
+ settings: Self::Settings,
+ loader_function: impl FnMut(&str) -> *const c_void,
+ ) -> (Self, Self::Renderer) {
+ let gl = glow::Context::from_loader_function(loader_function);
- let adapter = connection
- .create_hardware_adapter()
- .expect("Create adapter");
+ gl.clear_color(1.0, 1.0, 1.0, 1.0);
- let mut device =
- connection.create_device(&adapter).expect("Create device");
+ // Enable auto-conversion from/to sRGB
+ gl.enable(glow::FRAMEBUFFER_SRGB);
- let context_descriptor = device
- .create_context_descriptor(&surfman::ContextAttributes {
- version: surfman::GLVersion::new(3, 0),
- flags: surfman::ContextAttributeFlags::empty(),
- })
- .expect("Create context descriptor");
+ // Enable alpha blending
+ gl.enable(glow::BLEND);
+ gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA);
- let gl_context = device
- .create_context(&context_descriptor)
- .expect("Create context");
+ let renderer = Renderer::new(Backend::new(&gl, settings));
- Self {
- connection,
- device,
- gl_context,
- gl: None,
- }
- }
-
- fn create_renderer(&mut self, settings: Settings) -> Renderer {
- self.device
- .make_context_current(&self.gl_context)
- .expect("Make context current");
-
- Renderer::new(crate::Backend::new(self.gl.as_ref().unwrap(), settings))
- }
-
- fn create_surface<W: HasRawWindowHandle>(
- &mut self,
- window: &W,
- ) -> Self::Surface {
- let native_widget = self
- .connection
- .create_native_widget_from_rwh(window.raw_window_handle())
- .expect("Create widget");
-
- let surface = self
- .device
- .create_surface(
- &self.gl_context,
- surfman::SurfaceAccess::GPUOnly,
- surfman::SurfaceType::Widget { native_widget },
- )
- .expect("Create surface");
-
- let surfman::SurfaceInfo { .. } = self.device.surface_info(&surface);
-
- self.device
- .bind_surface_to_context(&mut self.gl_context, surface)
- .expect("Bind surface to context");
-
- self.device
- .make_context_current(&self.gl_context)
- .expect("Make context current");
-
- self.gl = Some(glow::Context::from_loader_function(|s| {
- self.device.get_proc_address(&self.gl_context, s)
- }));
-
- //let mut framebuffer =
- // skia_safe::gpu::gl::FramebufferInfo::from_fboid(framebuffer_object);
-
- //framebuffer.format = gl::RGBA8;
-
- //framebuffer
+ (Self { gl }, renderer)
}
- fn create_swap_chain(
- &mut self,
- _surface: &Self::Surface,
- width: u32,
- height: u32,
- ) -> Self::SwapChain {
- let mut surface = self
- .device
- .unbind_surface_from_context(&mut self.gl_context)
- .expect("Unbind surface")
- .expect("Active surface");
-
- self.device
- .resize_surface(
- &self.gl_context,
- &mut surface,
- euclid::Size2D::new(width as i32, height as i32),
- )
- .expect("Resize surface");
-
- self.device
- .bind_surface_to_context(&mut self.gl_context, surface)
- .expect("Bind surface to context");
-
- let gl = self.gl.as_ref().unwrap();
-
+ fn resize_viewport(&mut self, physical_size: Size<u32>) {
unsafe {
- gl.viewport(0, 0, width as i32, height as i32);
- gl.clear_color(1.0, 1.0, 1.0, 1.0);
-
- // Enable auto-conversion from/to sRGB
- gl.enable(glow::FRAMEBUFFER_SRGB);
-
- // Enable alpha blending
- gl.enable(glow::BLEND);
- gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA);
+ self.gl.viewport(
+ 0,
+ 0,
+ physical_size.width as i32,
+ physical_size.height as i32,
+ );
}
}
fn draw<T: AsRef<str>>(
&mut self,
renderer: &mut Self::Renderer,
- swap_chain: &mut Self::SwapChain,
viewport: &Viewport,
output: &<Self::Renderer as iced_native::Renderer>::Output,
overlay: &[T],
) -> mouse::Interaction {
- let gl = self.gl.as_ref().unwrap();
+ let gl = &self.gl;
unsafe {
gl.clear(glow::COLOR_BUFFER_BIT);
}
- let mouse = renderer.backend_mut().draw(gl, viewport, output, overlay);
-
- {
- let mut surface = self
- .device
- .unbind_surface_from_context(&mut self.gl_context)
- .expect("Unbind surface")
- .expect("Active surface");
-
- self.device
- .present_surface(&self.gl_context, &mut surface)
- .expect("Present surface");
-
- self.device
- .bind_surface_to_context(&mut self.gl_context, surface)
- .expect("Bind surface to context");
- }
-
- mouse
- }
-}
-
-impl Drop for Compositor {
- fn drop(&mut self) {
- self.device
- .destroy_context(&mut self.gl_context)
- .expect("Destroy context");
+ renderer.backend_mut().draw(gl, viewport, output, overlay)
}
}
diff --git a/glutin/Cargo.toml b/glutin/Cargo.toml
new file mode 100644
index 00000000..4652112c
--- /dev/null
+++ b/glutin/Cargo.toml
@@ -0,0 +1,30 @@
+[package]
+name = "iced_glutin"
+version = "0.1.0"
+authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
+edition = "2018"
+description = "A glutin runtime for Iced"
+license = "MIT"
+repository = "https://github.com/hecrj/iced"
+documentation = "https://docs.rs/iced_glutin"
+keywords = ["gui", "ui", "graphics", "interface", "widgets"]
+categories = ["gui"]
+
+[features]
+debug = ["iced_winit/debug"]
+
+[dependencies]
+glutin = "0.24"
+
+[dependencies.iced_native]
+version = "0.2"
+path = "../native"
+
+[dependencies.iced_winit]
+version = "0.1"
+path = "../winit"
+
+[dependencies.iced_graphics]
+version = "0.1"
+path = "../graphics"
+features = ["opengl"]
diff --git a/glutin/README.md b/glutin/README.md
new file mode 100644
index 00000000..34dec1b3
--- /dev/null
+++ b/glutin/README.md
@@ -0,0 +1,27 @@
+# `iced_winit`
+[![Documentation](https://docs.rs/iced_winit/badge.svg)][documentation]
+[![Crates.io](https://img.shields.io/crates/v/iced_winit.svg)](https://crates.io/crates/iced_winit)
+[![License](https://img.shields.io/crates/l/iced_winit.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
+[![project chat](https://img.shields.io/badge/chat-on_zulip-brightgreen.svg)](https://iced.zulipchat.com)
+
+`iced_winit` offers some convenient abstractions on top of [`iced_native`] to quickstart development when using [`winit`].
+
+It exposes a renderer-agnostic `Application` trait that can be implemented and then run with a simple call. The use of this trait is optional. A `conversion` module is provided for users that decide to implement a custom event loop.
+
+![iced_winit](../docs/graphs/winit.png)
+
+[documentation]: https://docs.rs/iced_winit
+[`iced_native`]: ../native
+[`winit`]: https://github.com/rust-windowing/winit
+
+## Installation
+Add `iced_winit` as a dependency in your `Cargo.toml`:
+
+```toml
+iced_winit = "0.1"
+```
+
+__Iced moves fast and the `master` branch can contain breaking changes!__ If
+you want to learn about a specific release, check out [the release list].
+
+[the release list]: https://github.com/hecrj/iced/releases
diff --git a/glutin/src/application.rs b/glutin/src/application.rs
new file mode 100644
index 00000000..919897a8
--- /dev/null
+++ b/glutin/src/application.rs
@@ -0,0 +1,429 @@
+use crate::{
+ mouse, Cache, Command, Element, Executor, Runtime, Size, Subscription,
+ UserInterface,
+};
+use iced_graphics::window;
+use iced_graphics::Viewport;
+use iced_winit::conversion;
+use iced_winit::{Clipboard, Debug, Mode, Proxy, Settings};
+
+/// An interactive, native cross-platform application.
+///
+/// This trait is the main entrypoint of Iced. Once implemented, you can run
+/// your GUI application by simply calling [`run`](#method.run). It will run in
+/// its own window.
+///
+/// An [`Application`](trait.Application.html) can execute asynchronous actions
+/// by returning a [`Command`](struct.Command.html) in some of its methods.
+///
+/// When using an [`Application`] with the `debug` feature enabled, a debug view
+/// can be toggled by pressing `F12`.
+pub trait Application: Sized {
+ /// The graphics backend to use to draw the [`Application`].
+ ///
+ /// [`Application`]: trait.Application.html
+ type Compositor: window::GLCompositor;
+
+ /// The [`Executor`] that will run commands and subscriptions.
+ ///
+ /// [`Executor`]: trait.Executor.html
+ type Executor: Executor;
+
+ /// The type of __messages__ your [`Application`] will produce.
+ ///
+ /// [`Application`]: trait.Application.html
+ type Message: std::fmt::Debug + Send;
+
+ /// The data needed to initialize your [`Application`].
+ ///
+ /// [`Application`]: trait.Application.html
+ type Flags;
+
+ /// Initializes the [`Application`] with the flags provided to
+ /// [`run`] as part of the [`Settings`].
+ ///
+ /// Here is where you should return the initial state of your app.
+ ///
+ /// Additionally, you can return a [`Command`](struct.Command.html) if you
+ /// need to perform some async action in the background on startup. This is
+ /// useful if you want to load state from a file, perform an initial HTTP
+ /// request, etc.
+ ///
+ /// [`Application`]: trait.Application.html
+ /// [`run`]: #method.run.html
+ /// [`Settings`]: struct.Settings.html
+ fn new(flags: Self::Flags) -> (Self, Command<Self::Message>);
+
+ /// Returns the current title of the [`Application`].
+ ///
+ /// This title can be dynamic! The runtime will automatically update the
+ /// title of your application when necessary.
+ ///
+ /// [`Application`]: trait.Application.html
+ fn title(&self) -> String;
+
+ /// Handles a __message__ and updates the state of the [`Application`].
+ ///
+ /// This is where you define your __update logic__. All the __messages__,
+ /// produced by either user interactions or commands, will be handled by
+ /// this method.
+ ///
+ /// Any [`Command`] returned will be executed immediately in the background.
+ ///
+ /// [`Application`]: trait.Application.html
+ /// [`Command`]: struct.Command.html
+ fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
+
+ /// Returns the event `Subscription` for the current state of the
+ /// application.
+ ///
+ /// The messages produced by the `Subscription` will be handled by
+ /// [`update`](#tymethod.update).
+ ///
+ /// A `Subscription` will be kept alive as long as you keep returning it!
+ ///
+ /// By default, it returns an empty subscription.
+ fn subscription(&self) -> Subscription<Self::Message> {
+ Subscription::none()
+ }
+
+ /// Returns the widgets to display in the [`Application`].
+ ///
+ /// These widgets can produce __messages__ based on user interaction.
+ ///
+ /// [`Application`]: trait.Application.html
+ fn view(
+ &mut self,
+ ) -> Element<
+ '_,
+ Self::Message,
+ <Self::Compositor as window::GLCompositor>::Renderer,
+ >;
+
+ /// Returns the current [`Application`] mode.
+ ///
+ /// The runtime will automatically transition your application if a new mode
+ /// is returned.
+ ///
+ /// By default, an application will run in windowed mode.
+ ///
+ /// [`Application`]: trait.Application.html
+ fn mode(&self) -> Mode {
+ Mode::Windowed
+ }
+
+ /// Runs the [`Application`] with the provided [`Settings`].
+ ///
+ /// On native platforms, this method will take control of the current thread
+ /// and __will NOT return__.
+ ///
+ /// It should probably be that last thing you call in your `main` function.
+ ///
+ /// [`Application`]: trait.Application.html
+ /// [`Settings`]: struct.Settings.html
+ fn run(
+ settings: Settings<Self::Flags>,
+ backend_settings: <Self::Compositor as window::GLCompositor>::Settings,
+ ) where
+ Self: 'static,
+ {
+ use glutin::{
+ event::{self, WindowEvent},
+ event_loop::{ControlFlow, EventLoop},
+ ContextBuilder,
+ };
+ use iced_graphics::window::GLCompositor as _;
+
+ let mut debug = Debug::new();
+
+ debug.startup_started();
+ let event_loop = EventLoop::with_user_event();
+ let mut external_messages = Vec::new();
+
+ let mut runtime = {
+ let executor = Self::Executor::new().expect("Create executor");
+
+ Runtime::new(executor, Proxy::new(event_loop.create_proxy()))
+ };
+
+ let flags = settings.flags;
+ let (mut application, init_command) =
+ runtime.enter(|| Self::new(flags));
+ runtime.spawn(init_command);
+
+ let subscription = application.subscription();
+ runtime.track(subscription);
+
+ let mut title = application.title();
+ let mut mode = application.mode();
+
+ let context = {
+ let window_builder = settings.window.into_builder(
+ &title,
+ mode,
+ event_loop.primary_monitor(),
+ );
+
+ let context = ContextBuilder::new()
+ .with_vsync(true)
+ .build_windowed(window_builder, &event_loop)
+ .expect("Open window");
+
+ #[allow(unsafe_code)]
+ unsafe {
+ context.make_current().expect("Make OpenGL context current")
+ }
+ };
+
+ let physical_size = context.window().inner_size();
+ let mut viewport = Viewport::with_physical_size(
+ Size::new(physical_size.width, physical_size.height),
+ context.window().scale_factor(),
+ );
+ let mut resized = false;
+
+ let clipboard = Clipboard::new(&context.window());
+
+ #[allow(unsafe_code)]
+ let (mut compositor, mut renderer) = unsafe {
+ Self::Compositor::new(backend_settings, |address| {
+ context.get_proc_address(address)
+ })
+ };
+
+ let user_interface = build_user_interface(
+ &mut application,
+ Cache::default(),
+ &mut renderer,
+ viewport.logical_size(),
+ &mut debug,
+ );
+
+ debug.draw_started();
+ let mut primitive = user_interface.draw(&mut renderer);
+ debug.draw_finished();
+
+ let mut cache = Some(user_interface.into_cache());
+ let mut events = Vec::new();
+ let mut mouse_interaction = mouse::Interaction::default();
+ let mut modifiers = glutin::event::ModifiersState::default();
+ debug.startup_finished();
+
+ context.window().request_redraw();
+
+ event_loop.run(move |event, _, control_flow| match event {
+ event::Event::MainEventsCleared => {
+ if events.is_empty() && external_messages.is_empty() {
+ return;
+ }
+
+ let mut user_interface = build_user_interface(
+ &mut application,
+ cache.take().unwrap(),
+ &mut renderer,
+ viewport.logical_size(),
+ &mut debug,
+ );
+
+ debug.event_processing_started();
+ events
+ .iter()
+ .cloned()
+ .for_each(|event| runtime.broadcast(event));
+
+ let mut messages = user_interface.update(
+ events.drain(..),
+ clipboard
+ .as_ref()
+ .map(|c| c as &dyn iced_native::Clipboard),
+ &renderer,
+ );
+ messages.extend(external_messages.drain(..));
+ debug.event_processing_finished();
+
+ if messages.is_empty() {
+ debug.draw_started();
+ primitive = user_interface.draw(&mut renderer);
+ debug.draw_finished();
+
+ cache = Some(user_interface.into_cache());
+ } else {
+ // When there are messages, we are forced to rebuild twice
+ // for now :^)
+ let temp_cache = user_interface.into_cache();
+
+ for message in messages {
+ debug.log_message(&message);
+
+ debug.update_started();
+ let command =
+ runtime.enter(|| application.update(message));
+ runtime.spawn(command);
+ debug.update_finished();
+ }
+
+ let subscription = application.subscription();
+ runtime.track(subscription);
+
+ // Update window title
+ let new_title = application.title();
+
+ if title != new_title {
+ context.window().set_title(&new_title);
+
+ title = new_title;
+ }
+
+ // Update window mode
+ let new_mode = application.mode();
+
+ if mode != new_mode {
+ context.window().set_fullscreen(
+ conversion::fullscreen(
+ context.window().current_monitor(),
+ new_mode,
+ ),
+ );
+
+ mode = new_mode;
+ }
+
+ let user_interface = build_user_interface(
+ &mut application,
+ temp_cache,
+ &mut renderer,
+ viewport.logical_size(),
+ &mut debug,
+ );
+
+ debug.draw_started();
+ primitive = user_interface.draw(&mut renderer);
+ debug.draw_finished();
+
+ cache = Some(user_interface.into_cache());
+ }
+
+ context.window().request_redraw();
+ }
+ event::Event::UserEvent(message) => {
+ external_messages.push(message);
+ }
+ event::Event::RedrawRequested(_) => {
+ debug.render_started();
+
+ if resized {
+ let physical_size = viewport.physical_size();
+
+ context.resize(glutin::dpi::PhysicalSize {
+ width: physical_size.width,
+ height: physical_size.height,
+ });
+ compositor.resize_viewport(physical_size);
+
+ resized = false;
+ }
+
+ let new_mouse_interaction = compositor.draw(
+ &mut renderer,
+ &viewport,
+ &primitive,
+ &debug.overlay(),
+ );
+
+ context.swap_buffers().expect("Swap buffers");
+ debug.render_finished();
+
+ if new_mouse_interaction != mouse_interaction {
+ context.window().set_cursor_icon(
+ conversion::mouse_interaction(new_mouse_interaction),
+ );
+
+ mouse_interaction = new_mouse_interaction;
+ }
+
+ // TODO: Handle animations!
+ // Maybe we can use `ControlFlow::WaitUntil` for this.
+ }
+ event::Event::WindowEvent {
+ event: window_event,
+ ..
+ } => {
+ match window_event {
+ WindowEvent::Resized(new_size) => {
+ let size = Size::new(new_size.width, new_size.height);
+
+ viewport = Viewport::with_physical_size(
+ size,
+ context.window().scale_factor(),
+ );
+ resized = true;
+ }
+ WindowEvent::CloseRequested => {
+ *control_flow = ControlFlow::Exit;
+ }
+ WindowEvent::ModifiersChanged(new_modifiers) => {
+ modifiers = new_modifiers;
+ }
+ #[cfg(target_os = "macos")]
+ WindowEvent::KeyboardInput {
+ input:
+ glutin::event::KeyboardInput {
+ virtual_keycode:
+ Some(glutin::event::VirtualKeyCode::Q),
+ state: glutin::event::ElementState::Pressed,
+ ..
+ },
+ ..
+ } if modifiers.logo() => {
+ *control_flow = ControlFlow::Exit;
+ }
+ #[cfg(feature = "debug")]
+ WindowEvent::KeyboardInput {
+ input:
+ glutin::event::KeyboardInput {
+ virtual_keycode:
+ Some(glutin::event::VirtualKeyCode::F12),
+ state: glutin::event::ElementState::Pressed,
+ ..
+ },
+ ..
+ } => debug.toggle(),
+ _ => {}
+ }
+
+ if let Some(event) = conversion::window_event(
+ &window_event,
+ viewport.scale_factor(),
+ modifiers,
+ ) {
+ events.push(event);
+ }
+ }
+ _ => {
+ *control_flow = ControlFlow::Wait;
+ }
+ })
+ }
+}
+
+fn build_user_interface<'a, A: Application>(
+ application: &'a mut A,
+ cache: Cache,
+ renderer: &mut <A::Compositor as window::GLCompositor>::Renderer,
+ size: Size,
+ debug: &mut Debug,
+) -> UserInterface<
+ 'a,
+ A::Message,
+ <A::Compositor as window::GLCompositor>::Renderer,
+> {
+ debug.view_started();
+ let view = application.view();
+ debug.view_finished();
+
+ debug.layout_started();
+ let user_interface = UserInterface::build(view, size, cache, renderer);
+ debug.layout_finished();
+
+ user_interface
+}
diff --git a/glutin/src/lib.rs b/glutin/src/lib.rs
new file mode 100644
index 00000000..2e2d03fc
--- /dev/null
+++ b/glutin/src/lib.rs
@@ -0,0 +1,15 @@
+//#![deny(missing_docs)]
+#![deny(missing_debug_implementations)]
+#![deny(unused_results)]
+#![deny(unsafe_code)]
+#![forbid(rust_2018_idioms)]
+
+#[doc(no_inline)]
+pub use iced_native::*;
+
+mod application;
+
+pub use application::Application;
+
+pub use iced_winit::settings::{self, Settings};
+pub use iced_winit::Mode;
diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml
index 12ad3f14..675bcb60 100644
--- a/graphics/Cargo.toml
+++ b/graphics/Cargo.toml
@@ -9,6 +9,7 @@ canvas = ["lyon"]
font-source = ["font-kit"]
font-fallback = []
font-icons = []
+opengl = []
[dependencies]
bytemuck = "1.2"
diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs
index 916b5c83..59b792f0 100644
--- a/graphics/src/layer.rs
+++ b/graphics/src/layer.rs
@@ -6,6 +6,7 @@ use crate::{
Vector, VerticalAlignment, Viewport,
};
+#[derive(Debug, Clone)]
pub struct Layer<'a> {
pub bounds: Rectangle,
pub quads: Vec<Quad>,
diff --git a/graphics/src/window.rs b/graphics/src/window.rs
index a7c8911b..380efb8c 100644
--- a/graphics/src/window.rs
+++ b/graphics/src/window.rs
@@ -1,3 +1,9 @@
mod compositor;
+#[cfg(feature = "opengl")]
+mod gl_compositor;
+
pub use compositor::Compositor;
+
+#[cfg(feature = "opengl")]
+pub use gl_compositor::GLCompositor;
diff --git a/graphics/src/window/gl_compositor.rs b/graphics/src/window/gl_compositor.rs
new file mode 100644
index 00000000..979d891e
--- /dev/null
+++ b/graphics/src/window/gl_compositor.rs
@@ -0,0 +1,24 @@
+use crate::{Size, Viewport};
+use iced_native::mouse;
+
+use core::ffi::c_void;
+
+pub trait GLCompositor: Sized {
+ type Renderer: iced_native::Renderer;
+ type Settings: Default;
+
+ unsafe fn new(
+ settings: Self::Settings,
+ loader_function: impl FnMut(&str) -> *const c_void,
+ ) -> (Self, Self::Renderer);
+
+ fn resize_viewport(&mut self, physical_size: Size<u32>);
+
+ fn draw<T: AsRef<str>>(
+ &mut self,
+ renderer: &mut Self::Renderer,
+ viewport: &Viewport,
+ output: &<Self::Renderer as iced_native::Renderer>::Output,
+ overlay: &[T],
+ ) -> mouse::Interaction;
+}
diff --git a/src/application.rs b/src/application.rs
index 0ae2ec55..644a4824 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -188,19 +188,19 @@ pub trait Application: Sized {
{
#[cfg(not(target_arch = "wasm32"))]
{
- let wgpu_settings = iced_wgpu::Settings {
+ let glow_settings = iced_glow::Settings {
default_font: settings.default_font,
antialiasing: if settings.antialiasing {
- Some(iced_wgpu::settings::Antialiasing::MSAAx4)
+ Some(iced_glow::settings::Antialiasing::MSAAx4)
} else {
None
},
- ..iced_wgpu::Settings::default()
+ ..iced_glow::Settings::default()
};
- <Instance<Self> as iced_winit::Application>::run(
+ <Instance<Self> as iced_glutin::Application>::run(
settings.into(),
- wgpu_settings,
+ glow_settings,
);
}
@@ -212,11 +212,11 @@ pub trait Application: Sized {
struct Instance<A: Application>(A);
#[cfg(not(target_arch = "wasm32"))]
-impl<A> iced_winit::Application for Instance<A>
+impl<A> iced_glutin::Application for Instance<A>
where
A: Application,
{
- type Compositor = iced_wgpu::window::Compositor;
+ type Compositor = iced_glow::window::Compositor;
type Executor = A::Executor;
type Flags = A::Flags;
type Message = A::Message;
@@ -231,10 +231,10 @@ where
self.0.title()
}
- fn mode(&self) -> iced_winit::Mode {
+ fn mode(&self) -> iced_glutin::Mode {
match self.0.mode() {
- window::Mode::Windowed => iced_winit::Mode::Windowed,
- window::Mode::Fullscreen => iced_winit::Mode::Fullscreen,
+ window::Mode::Windowed => iced_glutin::Mode::Windowed,
+ window::Mode::Fullscreen => iced_glutin::Mode::Fullscreen,
}
}
diff --git a/src/element.rs b/src/element.rs
index e5356fb6..e7504615 100644
--- a/src/element.rs
+++ b/src/element.rs
@@ -3,7 +3,7 @@
/// This is an alias of an `iced_native` element with a default `Renderer`.
#[cfg(not(target_arch = "wasm32"))]
pub type Element<'a, Message> =
- iced_winit::Element<'a, Message, iced_wgpu::Renderer>;
+ iced_glutin::Element<'a, Message, iced_glow::Renderer>;
#[cfg(target_arch = "wasm32")]
pub use iced_web::Element;
diff --git a/src/lib.rs b/src/lib.rs
index 2c08268b..58cc141d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -207,7 +207,7 @@ pub use sandbox::Sandbox;
pub use settings::Settings;
#[cfg(not(target_arch = "wasm32"))]
-use iced_winit as runtime;
+use iced_glutin as runtime;
#[cfg(target_arch = "wasm32")]
use iced_web as runtime;
diff --git a/src/settings.rs b/src/settings.rs
index 01ad0ee0..36685763 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -51,10 +51,10 @@ impl<Flags> Settings<Flags> {
}
#[cfg(not(target_arch = "wasm32"))]
-impl<Flags> From<Settings<Flags>> for iced_winit::Settings<Flags> {
- fn from(settings: Settings<Flags>) -> iced_winit::Settings<Flags> {
- iced_winit::Settings {
- window: iced_winit::settings::Window {
+impl<Flags> From<Settings<Flags>> for iced_glutin::Settings<Flags> {
+ fn from(settings: Settings<Flags>) -> iced_glutin::Settings<Flags> {
+ iced_glutin::Settings {
+ window: iced_glutin::settings::Window {
size: settings.window.size,
resizable: settings.window.resizable,
decorations: settings.window.decorations,
diff --git a/src/widget.rs b/src/widget.rs
index e33a6b2c..eebf5f2a 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -18,29 +18,27 @@
//! [`text_input::State`]: text_input/struct.State.html
#[cfg(not(target_arch = "wasm32"))]
mod platform {
- pub use iced_wgpu::widget::{
+ pub use iced_glow::widget::{
button, checkbox, container, pane_grid, progress_bar, radio,
- scrollable, slider, text_input, Text,
+ scrollable, slider, text_input, Column, Row, Space, Text,
};
#[cfg(feature = "canvas")]
#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))]
- pub use iced_wgpu::widget::canvas;
+ pub use iced_glow::widget::canvas;
#[cfg_attr(docsrs, doc(cfg(feature = "image")))]
pub mod image {
//! Display images in your user interface.
- pub use iced_winit::image::{Handle, Image};
+ pub use iced_glutin::image::{Handle, Image};
}
#[cfg_attr(docsrs, doc(cfg(feature = "svg")))]
pub mod svg {
//! Display vector graphics in your user interface.
- pub use iced_winit::svg::{Handle, Svg};
+ pub use iced_glutin::svg::{Handle, Svg};
}
- pub use iced_winit::Space;
-
#[doc(no_inline)]
pub use {
button::Button, checkbox::Checkbox, container::Container, image::Image,
@@ -52,18 +50,6 @@ mod platform {
#[cfg(feature = "canvas")]
#[doc(no_inline)]
pub use canvas::Canvas;
-
- /// A container that distributes its contents vertically.
- ///
- /// This is an alias of an `iced_native` column with a default `Renderer`.
- pub type Column<'a, Message> =
- iced_winit::Column<'a, Message, iced_wgpu::Renderer>;
-
- /// A container that distributes its contents horizontally.
- ///
- /// This is an alias of an `iced_native` row with a default `Renderer`.
- pub type Row<'a, Message> =
- iced_winit::Row<'a, Message, iced_wgpu::Renderer>;
}
#[cfg(target_arch = "wasm32")]
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 9196709b..ccab19f1 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -129,7 +129,6 @@ pub trait Application: Sized {
use winit::{
event::{self, WindowEvent},
event_loop::{ControlFlow, EventLoop},
- window::WindowBuilder,
};
let mut debug = Debug::new();
@@ -155,32 +154,11 @@ pub trait Application: Sized {
let mut title = application.title();
let mut mode = application.mode();
- let window = {
- let mut window_builder = WindowBuilder::new();
-
- let (width, height) = settings.window.size;
-
- window_builder = window_builder
- .with_title(&title)
- .with_inner_size(winit::dpi::LogicalSize { width, height })
- .with_resizable(settings.window.resizable)
- .with_decorations(settings.window.decorations)
- .with_fullscreen(conversion::fullscreen(
- event_loop.primary_monitor(),
- mode,
- ));
-
- #[cfg(target_os = "windows")]
- {
- use winit::platform::windows::WindowBuilderExtWindows;
-
- if let Some(parent) = settings.window.platform_specific.parent {
- window_builder = window_builder.with_parent_window(parent);
- }
- }
-
- window_builder.build(&event_loop).expect("Open window")
- };
+ let window = settings
+ .window
+ .into_builder(&title, mode, event_loop.primary_monitor())
+ .build(&event_loop)
+ .expect("Open window");
let physical_size = window.inner_size();
let mut viewport = Viewport::with_physical_size(
diff --git a/winit/src/lib.rs b/winit/src/lib.rs
index b0f235ad..9cf5dc0d 100644
--- a/winit/src/lib.rs
+++ b/winit/src/lib.rs
@@ -15,7 +15,7 @@
//! [`winit`]: https://github.com/rust-windowing/winit
//! [`Application`]: trait.Application.html
//! [`conversion`]: conversion
-#![deny(missing_docs)]
+//#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
#![forbid(unsafe_code)]
@@ -44,8 +44,7 @@ mod debug;
pub use application::Application;
pub use clipboard::Clipboard;
+pub use debug::Debug;
pub use mode::Mode;
+pub use proxy::Proxy;
pub use settings::Settings;
-
-use debug::Debug;
-use proxy::Proxy;
diff --git a/winit/src/proxy.rs b/winit/src/proxy.rs
index cff6ca72..ee96614a 100644
--- a/winit/src/proxy.rs
+++ b/winit/src/proxy.rs
@@ -5,6 +5,7 @@ use iced_native::futures::{
};
use std::pin::Pin;
+#[derive(Debug)]
pub struct Proxy<Message: 'static> {
raw: winit::event_loop::EventLoopProxy<Message>,
}
diff --git a/winit/src/settings.rs b/winit/src/settings.rs
index d58c51f0..751f5071 100644
--- a/winit/src/settings.rs
+++ b/winit/src/settings.rs
@@ -8,6 +8,11 @@ mod platform;
pub use platform::PlatformSpecific;
+use crate::conversion;
+use crate::Mode;
+use winit::monitor::MonitorHandle;
+use winit::window::WindowBuilder;
+
/// The settings of an application.
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Settings<Flags> {
@@ -38,6 +43,37 @@ pub struct Window {
pub platform_specific: platform::PlatformSpecific,
}
+impl Window {
+ pub fn into_builder(
+ self,
+ title: &str,
+ mode: Mode,
+ primary_monitor: MonitorHandle,
+ ) -> WindowBuilder {
+ let mut window_builder = WindowBuilder::new();
+
+ let (width, height) = self.size;
+
+ window_builder = window_builder
+ .with_title(title)
+ .with_inner_size(winit::dpi::LogicalSize { width, height })
+ .with_resizable(self.resizable)
+ .with_decorations(self.decorations)
+ .with_fullscreen(conversion::fullscreen(primary_monitor, mode));
+
+ #[cfg(target_os = "windows")]
+ {
+ use winit::platform::windows::WindowBuilderExtWindows;
+
+ if let Some(parent) = self.platform_specific.parent {
+ window_builder = window_builder.with_parent_window(parent);
+ }
+ }
+
+ window_builder
+ }
+}
+
impl Default for Window {
fn default() -> Window {
Window {
diff --git a/winit/src/size.rs b/winit/src/size.rs
deleted file mode 100644
index 7e3056d4..00000000
--- a/winit/src/size.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-pub struct Size {
- physical: winit::dpi::PhysicalSize<u32>,
- logical: winit::dpi::LogicalSize<f64>,
- scale_factor: f64,
-}
-
-impl Size {
- pub fn new(
- physical: winit::dpi::PhysicalSize<u32>,
- scale_factor: f64,
- ) -> Size {
- Size {
- logical: physical.to_logical(scale_factor),
- physical,
- scale_factor,
- }
- }
-
- pub fn physical(&self) -> winit::dpi::PhysicalSize<u32> {
- self.physical
- }
-
- pub fn logical(&self) -> winit::dpi::LogicalSize<f64> {
- self.logical
- }
-
- pub fn scale_factor(&self) -> f64 {
- self.scale_factor
- }
-}