use crate::{
error::Error,
event::Event,
helpers::MaybeStatic,
monitor::{ Size},
platform::imp,
};
use std::borrow::Cow;
pub struct Window {
pub(crate) inner: imp::WindowRepr,
}
pub(crate) trait WindowImpl {
fn events(&self) -> &[Event];
fn execute(&self, f: &mut dyn FnMut());
fn set_controls(&self, controls: Option<WindowControls>);
fn set_controls_async(&self, controls: Option<WindowControls>);
fn set_resizable(&self, resizable: bool);
fn set_resizable_async(&self, resizable: bool);
fn set_title(&self, title: &str);
fn set_title_async(&self, title: &str);
fn set_visible(&self, visible: bool);
fn set_visible_async(&self, visible: bool);
fn swap_events(&mut self);
}
impl Window {
pub const fn builder() -> WindowBuilder {
WindowBuilder::new()
}
}
impl Window {
#[inline]
pub fn events(&self) -> &[Event] {
self.inner.events()
}
#[inline]
pub fn execute<F>(&self, mut f: F)
where
F: FnMut(&Self) + Send,
{
self.inner.execute(&mut move || f(self));
}
#[inline]
pub fn set_controls(&self, controls: Option<WindowControls>) {
self.inner.set_controls(controls)
}
#[inline]
pub fn set_controls_async(&self, controls: Option<WindowControls>) {
self.inner.set_controls_async(controls)
}
#[inline]
pub fn set_resizable(&self, resizable: bool) {
self.inner.set_resizable(resizable)
}
#[inline]
pub fn set_resizable_async(&self, resizable: bool) {
self.inner.set_resizable_async(resizable)
}
#[inline]
pub fn set_title(&self, title: &str) {
self.inner.set_title(title);
}
#[inline]
pub fn set_title_async(&self, title: &str) {
self.inner.set_title_async(title);
}
#[inline]
pub fn set_visible(&self, visible: bool) {
self.inner.set_visible(visible);
}
#[inline]
pub fn set_visible_async(&self, visible: bool) {
self.inner.set_visible_async(visible);
}
#[inline]
pub fn swap_events(&mut self) {
self.inner.swap_events();
}
}
#[derive(Clone)]
pub struct WindowBuilder {
pub(crate) class_name: MaybeStatic<str>,
pub(crate) inner_size: Size,
pub(crate) style: WindowStyle,
pub(crate) title: MaybeStatic<str>,
}
impl WindowBuilder {
pub(crate) const fn new() -> Self {
Self {
class_name: MaybeStatic::Static("ramen_window_class"),
inner_size: Size::Logical(800.0, 608.0),
style: WindowStyle {
borderless: false,
controls: Some(WindowControls::no_maximize()),
resizable: true,
visible: true,
rtl_layout: false,
#[cfg(windows)]
tool_window: false,
},
title: MaybeStatic::Static("a nice window"),
}
}
pub fn build(&self) -> Result<Window, Error> {
imp::make_window(self).map(|inner| Window { inner })
}
}
impl WindowBuilder {
pub fn borderless(&mut self, borderless: bool) -> &mut Self {
self.style.borderless = borderless;
self
}
pub fn class_name<T>(&mut self, class_name: T) -> &mut Self
where
T: Into<Cow<'static, str>>,
{
self.class_name = match class_name.into() {
Cow::Borrowed(x) => x.into(),
Cow::Owned(x) => MaybeStatic::Dynamic(x.into()),
};
self
}
pub fn controls(&mut self, controls: Option<WindowControls>) -> &mut Self {
self.style.controls = controls;
self
}
pub fn inner_size(&mut self, inner_size: Size) -> &mut Self {
self.inner_size = inner_size;
self
}
pub fn resizable(&mut self, resizable: bool) -> &mut Self {
self.style.resizable = resizable;
self
}
pub fn rtl_layout(&mut self, rtl_layout: bool) -> &mut Self {
self.style.rtl_layout = rtl_layout;
self
}
pub fn title<T>(&mut self, title: T) -> &mut Self
where
T: Into<Cow<'static, str>>,
{
self.title = match title.into() {
Cow::Borrowed(x) => x.into(),
Cow::Owned(x) => MaybeStatic::Dynamic(x.into()),
};
self
}
pub fn visible(&mut self, visible: bool) -> &mut Self {
self.style.visible = visible;
self
}
}
impl Default for WindowBuilder {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct WindowControls {
pub minimize: bool,
pub maximize: bool,
pub close: bool,
}
impl WindowControls {
pub const fn new(minimize: bool, maximize: bool, close: bool) -> Self {
Self {
minimize,
maximize,
close,
}
}
pub const fn enabled() -> Self {
Self::new(true, true, true)
}
pub const fn no_maximize() -> Self {
Self::new(true, false, true)
}
pub(crate) fn to_bits(&self) -> u32 {
(self.minimize as u32) << 2 | (self.maximize as u32) << 1 | self.close as u32
}
pub(crate) fn from_bits(x: u32) -> Self {
Self {
minimize: x & (1 << 2) != 0,
maximize: x & (1 << 1) != 0,
close: x & 1 != 0,
}
}
}
impl Default for WindowControls {
fn default() -> Self {
Self::enabled()
}
}
#[derive(Default, Clone)]
pub(crate) struct WindowStyle {
pub borderless: bool,
pub resizable: bool,
pub visible: bool,
pub controls: Option<WindowControls>,
pub rtl_layout: bool,
#[cfg(windows)]
pub tool_window: bool,
}