Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate role-specific methods into their own traits #5

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions winit-core/src/event_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use raw_window_handle_05::HasRawDisplayHandle as HasRawDisplayHandle05;

use crate::application::Application;
use crate::monitor::{Monitor, MonitorId};
use crate::window::{Window, WindowAttributes, WindowId};
use crate::window::{PopupAttributes, Surface, WindowAttributes, WindowId};

use self::proxy::EventLoopProxy;

Expand Down Expand Up @@ -33,13 +33,16 @@ pub trait EventLoopHandle: HasDisplayHandle {
fn proxy(&self) -> Arc<dyn EventLoopProxy>;

/// Request to create a window.
fn create_window(&mut self, attributes: &WindowAttributes) -> Result<(), ()>;
fn create_toplevel(&mut self, attributes: &WindowAttributes) -> Result<(), ()>;

/// Requests to create a popup.
fn create_popup(&mut self, parent: WindowId, attributes: &PopupAttributes) -> Result<(), ()>;

fn num_windows(&self) -> usize;

fn get_window(&self, window_id: WindowId) -> Option<&dyn Window>;
fn get_window(&self, window_id: WindowId) -> Option<&dyn Surface>;

fn get_window_mut(&mut self, window_id: WindowId) -> Option<&mut dyn Window>;
fn get_window_mut(&mut self, window_id: WindowId) -> Option<&mut dyn Surface>;

fn get_monitor(&self, monitor_id: MonitorId) -> Option<&dyn Monitor>;

Expand Down
158 changes: 149 additions & 9 deletions winit-core/src/window.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
// TODO figure out how to do WindowId.

use std::any::Any;

pub use raw_window_handle::HasWindowHandle;
pub use raw_window_handle_05::HasRawWindowHandle as HasRawWindowHandle05;

use crate::dpi::{LogicalSize, PhysicalSize, Position, Size};
use crate::dpi::{
self, LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size,
};
use crate::monitor::MonitorId;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WindowId(pub u128);

/// Common requests to perform on the window.
pub trait Window: HasWindowHandle + HasRawWindowHandle05 {
pub enum WindowRole<'a> {
Toplevel(&'a dyn Toplevel),
Popup(&'a dyn Popup),
}

pub enum WindowRoleMut<'a> {
Toplevel(&'a mut dyn Toplevel),
Popup(&'a mut dyn Popup),
}

/// Common API for all rendering targets.
pub trait Surface: HasWindowHandle + HasRawWindowHandle05 {
fn id(&self) -> WindowId;

fn scale_factor(&self) -> f64;

fn request_redraw(&mut self);

fn inner_size(&self) -> PhysicalSize<u32>;

/// Downcasts this surface to its specific type.
fn role(&self) -> WindowRole;
/// Downcasts this surface to its specific type. Returns a mutable reference.
fn role_mut(&mut self) -> WindowRoleMut;
}

/// API for toplevel windows and dialogs.
pub trait Toplevel: Surface {
/// Gets the current title of the window.
fn title(&self) -> &str;

Expand All @@ -22,12 +50,6 @@ pub trait Window: HasWindowHandle + HasRawWindowHandle05 {

fn set_theme(&mut self, theme: Option<Theme>);

fn scale_factor(&self) -> f64;

fn request_redraw(&mut self);

fn inner_size(&self) -> PhysicalSize<u32>;

fn set_minimized(&mut self, minimize: bool);

fn set_maximized(&mut self, maximized: bool);
Expand All @@ -37,6 +59,11 @@ pub trait Window: HasWindowHandle + HasRawWindowHandle05 {
fn primary_monitor(&self) -> Option<MonitorId>;
}

/// API for popups.
pub trait Popup: Surface {
// fn set_position(&mut self, position: PhysicalPosition<u32>);
}

/// Attributes to use when creating a window.
#[derive(Debug, Clone)]
pub struct WindowAttributes {
Expand Down Expand Up @@ -291,6 +318,119 @@ impl WindowAttributes {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum AnchorDirection {
Center = 0,
North = 1,
Northeast = 2,
East = 3,
Southeast = 4,
South = 5,
Southwest = 6,
West = 7,
Northwest = 8,
}

bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AnchorHints: u32 {
const NONE = 0;
const FLIP_X = 1 << 0;
const FLIP_Y = 1 << 1;
const SLIDE_X = 1 << 2;
const SLIDE_Y = 1 << 3;
const RESIZE_X = 1 << 4;
const RESIZE_Y = 1 << 5;
}
}

#[derive(Debug, Clone)]
pub struct PopupAttributes {
pub inner_size: Size,
pub anchor_rect: (Position, Size),
pub rect_anchor: AnchorDirection,
pub surface_anchor: AnchorDirection,
pub offset: Position,
pub anchor_hints: AnchorHints,
}

impl Default for PopupAttributes {
fn default() -> Self {
Self {
inner_size: LogicalSize::new(100.0, 75.0).into(),
anchor_rect: (
LogicalPosition::new(0.0, 0.0).into(),
LogicalSize::new(100.0, 100.0).into(),
),
rect_anchor: AnchorDirection::Center,
surface_anchor: AnchorDirection::Center,
offset: LogicalPosition::new(0.0, 0.0).into(),
anchor_hints: AnchorHints::NONE,
}
}
}

impl PopupAttributes {
pub fn inner_size(&self) -> Size {
self.inner_size
}

pub fn with_inner_size<S: Into<Size>>(mut self, size: S) -> Self {
self.inner_size = size.into();
self
}

pub fn anchor_rect(&self) -> (Position, Size) {
self.anchor_rect
}

pub fn with_anchor_rect<P: Into<Position>, S: Into<Size>>(
mut self,
top_left: P,
size: S,
) -> Self {
self.anchor_rect = (top_left.into(), size.into());
self
}

pub fn rect_anchor(&self) -> AnchorDirection {
self.rect_anchor
}

pub fn with_rect_anchor(mut self, direction: AnchorDirection) -> Self {
self.rect_anchor = direction;
self
}

pub fn surface_anchor(&self) -> AnchorDirection {
self.surface_anchor
}

pub fn with_surface_anchor(mut self, direction: AnchorDirection) -> Self {
self.surface_anchor = direction;
self
}

pub fn offset(&self) -> Position {
self.offset
}

pub fn with_offset<P: Into<Position>>(mut self, offset: P) -> Self {
self.offset = offset.into();
self
}

pub fn anchor_hints(&self) -> AnchorHints {
self.anchor_hints
}

pub fn with_anchor_hints(mut self, hints: AnchorHints) -> Self {
self.anchor_hints = hints;
self
}
}

/// A window level groups windows with respect to their z-position.
///
/// The relative ordering between windows in different window levels is fixed.
Expand Down
41 changes: 29 additions & 12 deletions winit-wayland/examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ use std::time::Duration;
use winit_core::application::{Application, ApplicationWindow, StartCause};
use winit_core::dpi::PhysicalSize;
use winit_core::event_loop::{EventLoopHandle, EventLoopRequests};
use winit_core::window::WindowId;
use winit_core::window::{Toplevel, WindowId, WindowRole};
use winit_wayland::event_loop::EventLoop;
use winit_wayland::MyCoolTrait;

use softbuffer::{Context, Surface};

const DARK_GRAY: u32 = 0xFF181818;
const ORANGE: u32 = 0xFF_FF8000;

pub struct State {
context: Context,
Expand Down Expand Up @@ -39,7 +40,7 @@ impl Application for State {

fn new_events(&mut self, loop_handle: &mut dyn EventLoopHandle, start_cause: StartCause) {
println!("Start cause {start_cause:?}");
let _ = loop_handle.create_window(&Default::default());
let _ = loop_handle.create_toplevel(&Default::default());
}

fn about_to_wait(&mut self, _: &mut dyn EventLoopHandle) {
Expand Down Expand Up @@ -89,17 +90,33 @@ impl ApplicationWindow for State {
_ => return,
};

if let Some(monitor_id) = window.current_monitor() {
let monitor = loop_handle.get_monitor(monitor_id).unwrap();
println!("Current monitor name {:?}", monitor.name());
match window.role() {
WindowRole::Toplevel(toplevel) => {
if let Some(monitor_id) = toplevel.current_monitor() {
let monitor = loop_handle.get_monitor(monitor_id).unwrap();
println!("Current monitor name {:?}", monitor.name());
}

let size = window.inner_size();
let _ = surface.resize(
NonZeroU32::new(size.width).unwrap(),
NonZeroU32::new(size.height).unwrap(),
);
let mut buffer = surface.buffer_mut().unwrap();
buffer.fill(DARK_GRAY);
buffer.present().unwrap();
},
WindowRole::Popup(popup) => {
let size = window.inner_size();
let _ = surface.resize(
NonZeroU32::new(size.width).unwrap(),
NonZeroU32::new(size.height).unwrap(),
);
let mut buffer = surface.buffer_mut().unwrap();
buffer.fill(ORANGE);
buffer.present().unwrap();
},
}

let size = window.inner_size();
let _ = surface
.resize(NonZeroU32::new(size.width).unwrap(), NonZeroU32::new(size.height).unwrap());
let mut buffer = surface.buffer_mut().unwrap();
buffer.fill(DARK_GRAY);
buffer.present().unwrap();
}

fn destroyed(&mut self, loop_handle: &mut dyn EventLoopHandle, _: WindowId) {
Expand Down
4 changes: 2 additions & 2 deletions winit-wayland/src/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use sctk::seat::{Capability as SeatCapability, SeatHandler, SeatState};
use winit_core::application::Application;
use winit_core::event_loop::proxy::EventLoopProxy as CoreEventLoopProxy;
use winit_core::event_loop::{EventLoopHandle, EventLoopRequests};
use winit_core::window::{Window as CoreWindow, WindowId};
use winit_core::window::{Surface as CoreSurface, WindowId};

use crate::state::WinitState;
use crate::MyCoolTrait;
Expand Down Expand Up @@ -93,7 +93,7 @@ impl<T: Application + 'static> EventLoopRequests<T> for EventLoop<T> {
let user = self.state.user.as_mut().unwrap();

for (window_id, window) in &mut winit.windows {
if mem::take(&mut window.redraw) {
if window.take_redraw() {
redraw.push(*window_id);
}
}
Expand Down
2 changes: 2 additions & 0 deletions winit-wayland/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use winit_core::window::WindowId;
pub mod event_loop;
pub mod monitor;
pub mod state;
pub mod toplevel;
pub mod popup;
pub mod window;

/// Get the WindowId out of the surface.
Expand Down
Loading