summaryrefslogtreecommitdiffstats
path: root/winit/src
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-07-08 11:44:40 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-07-08 11:44:40 +0200
commitf3dfaa2c43bad16fc91660b2b73cb9173549e7ec (patch)
tree353365f4dd1e3136bc651ac8c1572f62fff1304b /winit/src
parent072ec69d53d2708d8fd1693151bcec7305efccf8 (diff)
parent5c4f5ae5ecb36703a95cafb2cd58692529c9466d (diff)
downloadiced-f3dfaa2c43bad16fc91660b2b73cb9173549e7ec.tar.gz
iced-f3dfaa2c43bad16fc91660b2b73cb9173549e7ec.tar.bz2
iced-f3dfaa2c43bad16fc91660b2b73cb9173549e7ec.zip
Merge branch 'master' into feature/pane-grid-titlebar
Diffstat (limited to 'winit/src')
-rw-r--r--winit/src/application.rs91
-rw-r--r--winit/src/conversion.rs15
-rw-r--r--winit/src/settings.rs27
3 files changed, 125 insertions, 8 deletions
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 73ac72b2..5b93c8af 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -1,6 +1,6 @@
//! Create interactive, native cross-platform applications.
use crate::{
- conversion, mouse, Clipboard, Command, Debug, Executor, Mode, Proxy,
+ conversion, mouse, Clipboard, Color, Command, Debug, Executor, Mode, Proxy,
Runtime, Settings, Size, Subscription,
};
use iced_graphics::window;
@@ -73,6 +73,32 @@ pub trait Application: Program {
fn mode(&self) -> Mode {
Mode::Windowed
}
+
+ /// Returns the background [`Color`] of the [`Application`].
+ ///
+ /// By default, it returns [`Color::WHITE`].
+ ///
+ /// [`Color`]: struct.Color.html
+ /// [`Application`]: trait.Application.html
+ /// [`Color::WHITE`]: struct.Color.html#const.WHITE
+ fn background_color(&self) -> Color {
+ Color::WHITE
+ }
+
+ /// Returns the scale factor of the [`Application`].
+ ///
+ /// It can be used to dynamically control the size of the UI at runtime
+ /// (i.e. zooming).
+ ///
+ /// For instance, a scale factor of `2.0` will make widgets twice as big,
+ /// while a scale factor of `0.5` will shrink them to half their size.
+ ///
+ /// By default, it returns `1.0`.
+ ///
+ /// [`Application`]: trait.Application.html
+ fn scale_factor(&self) -> f64 {
+ 1.0
+ }
}
/// Runs an [`Application`] with an executor, compositor, and the provided
@@ -112,6 +138,8 @@ pub fn run<A, E, C>(
let mut title = application.title();
let mut mode = application.mode();
+ let mut background_color = application.background_color();
+ let mut scale_factor = application.scale_factor();
let window = settings
.window
@@ -120,13 +148,14 @@ pub fn run<A, E, C>(
.expect("Open window");
let clipboard = Clipboard::new(&window);
+ let mut cursor_position = winit::dpi::PhysicalPosition::new(-1.0, -1.0);
let mut mouse_interaction = mouse::Interaction::default();
let mut modifiers = winit::event::ModifiersState::default();
let physical_size = window.inner_size();
let mut viewport = Viewport::with_physical_size(
Size::new(physical_size.width, physical_size.height),
- window.scale_factor(),
+ window.scale_factor() * scale_factor,
);
let mut resized = false;
@@ -143,6 +172,7 @@ pub fn run<A, E, C>(
let mut state = program::State::new(
application,
viewport.logical_size(),
+ conversion::cursor_position(cursor_position, viewport.scale_factor()),
&mut renderer,
&mut debug,
);
@@ -150,10 +180,18 @@ pub fn run<A, E, C>(
event_loop.run(move |event, _, control_flow| match event {
event::Event::MainEventsCleared => {
+ if state.is_queue_empty() {
+ return;
+ }
+
let command = runtime.enter(|| {
state.update(
- clipboard.as_ref().map(|c| c as _),
viewport.logical_size(),
+ conversion::cursor_position(
+ cursor_position,
+ viewport.scale_factor(),
+ ),
+ clipboard.as_ref().map(|c| c as _),
&mut renderer,
&mut debug,
)
@@ -189,6 +227,39 @@ pub fn run<A, E, C>(
mode = new_mode;
}
+
+ // Update background color
+ background_color = program.background_color();
+
+ // Update scale factor
+ let new_scale_factor = program.scale_factor();
+
+ if scale_factor != new_scale_factor {
+ let size = window.inner_size();
+
+ viewport = Viewport::with_physical_size(
+ Size::new(size.width, size.height),
+ window.scale_factor() * new_scale_factor,
+ );
+
+ // We relayout the UI with the new logical size.
+ // The queue is empty, therefore this will never produce
+ // a `Command`.
+ //
+ // TODO: Properly queue `WindowResized`
+ let _ = state.update(
+ viewport.logical_size(),
+ conversion::cursor_position(
+ cursor_position,
+ viewport.scale_factor(),
+ ),
+ clipboard.as_ref().map(|c| c as _),
+ &mut renderer,
+ &mut debug,
+ );
+
+ scale_factor = new_scale_factor;
+ }
}
window.request_redraw();
@@ -215,6 +286,7 @@ pub fn run<A, E, C>(
&mut renderer,
&mut swap_chain,
&viewport,
+ background_color,
state.primitive(),
&debug.overlay(),
);
@@ -239,7 +311,9 @@ pub fn run<A, E, C>(
handle_window_event(
&window_event,
&window,
+ scale_factor,
control_flow,
+ &mut cursor_position,
&mut modifiers,
&mut viewport,
&mut resized,
@@ -266,7 +340,9 @@ pub fn run<A, E, C>(
pub fn handle_window_event(
event: &winit::event::WindowEvent<'_>,
window: &winit::window::Window,
+ scale_factor: f64,
control_flow: &mut winit::event_loop::ControlFlow,
+ cursor_position: &mut winit::dpi::PhysicalPosition<f64>,
modifiers: &mut winit::event::ModifiersState,
viewport: &mut Viewport,
resized: &mut bool,
@@ -278,13 +354,18 @@ pub fn handle_window_event(
WindowEvent::Resized(new_size) => {
let size = Size::new(new_size.width, new_size.height);
- *viewport =
- Viewport::with_physical_size(size, window.scale_factor());
+ *viewport = Viewport::with_physical_size(
+ size,
+ window.scale_factor() * scale_factor,
+ );
*resized = true;
}
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
+ WindowEvent::CursorMoved { position, .. } => {
+ *cursor_position = *position;
+ }
WindowEvent::ModifiersChanged(new_modifiers) => {
*modifiers = *new_modifiers;
}
diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs
index b887db6e..cfa76e88 100644
--- a/winit/src/conversion.rs
+++ b/winit/src/conversion.rs
@@ -4,7 +4,7 @@
//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
use crate::{
keyboard::{self, KeyCode, ModifiersState},
- mouse, window, Event, Mode,
+ mouse, window, Event, Mode, Point,
};
/// Converts a winit window event into an iced event.
@@ -92,6 +92,9 @@ pub fn window_event(
}
}
})),
+ WindowEvent::ModifiersChanged(new_modifiers) => Some(Event::Keyboard(
+ keyboard::Event::ModifiersChanged(modifiers_state(*new_modifiers)),
+ )),
WindowEvent::HoveredFile(path) => {
Some(Event::Window(window::Event::FileHovered(path.clone())))
}
@@ -174,6 +177,16 @@ pub fn modifiers_state(
}
}
+/// Converts a physical cursor position to a logical `Point`.
+pub fn cursor_position(
+ position: winit::dpi::PhysicalPosition<f64>,
+ scale_factor: f64,
+) -> Point {
+ let logical_position = position.to_logical(scale_factor);
+
+ Point::new(logical_position.x, logical_position.y)
+}
+
/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code.
///
/// [`winit`]: https://github.com/rust-windowing/winit
diff --git a/winit/src/settings.rs b/winit/src/settings.rs
index 37cb832f..4155bf7d 100644
--- a/winit/src/settings.rs
+++ b/winit/src/settings.rs
@@ -14,7 +14,7 @@ use winit::monitor::MonitorHandle;
use winit::window::WindowBuilder;
/// The settings of an application.
-#[derive(Debug, Clone, Copy, PartialEq, Default)]
+#[derive(Debug, Clone, Default)]
pub struct Settings<Flags> {
/// The [`Window`] settings
///
@@ -28,17 +28,26 @@ pub struct Settings<Flags> {
}
/// The window settings of an application.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone)]
pub struct Window {
/// The size of the window.
pub size: (u32, u32),
+ /// The minimum size of the window.
+ pub min_size: Option<(u32, u32)>,
+
+ /// The maximum size of the window.
+ pub max_size: Option<(u32, u32)>,
+
/// Whether the window should be resizable or not.
pub resizable: bool,
/// Whether the window should have a border, a title bar, etc.
pub decorations: bool,
+ /// The window icon, which is also usually used in the taskbar
+ pub icon: Option<winit::window::Icon>,
+
/// Platform specific settings.
pub platform_specific: platform::PlatformSpecific,
}
@@ -60,8 +69,19 @@ impl Window {
.with_inner_size(winit::dpi::LogicalSize { width, height })
.with_resizable(self.resizable)
.with_decorations(self.decorations)
+ .with_window_icon(self.icon)
.with_fullscreen(conversion::fullscreen(primary_monitor, mode));
+ if let Some((width, height)) = self.min_size {
+ window_builder = window_builder
+ .with_min_inner_size(winit::dpi::LogicalSize { width, height });
+ }
+
+ if let Some((width, height)) = self.max_size {
+ window_builder = window_builder
+ .with_max_inner_size(winit::dpi::LogicalSize { width, height });
+ }
+
#[cfg(target_os = "windows")]
{
use winit::platform::windows::WindowBuilderExtWindows;
@@ -79,8 +99,11 @@ impl Default for Window {
fn default() -> Window {
Window {
size: (1024, 768),
+ min_size: None,
+ max_size: None,
resizable: true,
decorations: true,
+ icon: None,
platform_specific: Default::default(),
}
}