Skip to content

Commit

Permalink
Added ability to build and interact with a window
Browse files Browse the repository at this point in the history
  • Loading branch information
ecton committed Aug 30, 2023
1 parent d1ea1b2 commit 14ebcde
Show file tree
Hide file tree
Showing 8 changed files with 358 additions and 50 deletions.
5 changes: 4 additions & 1 deletion crates/gooey-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use alot::OrderedLots;
pub use {figures as math, gooey_reactor as reactor};
pub mod graphics;
pub mod style;
pub mod window;
// mod tree;
pub use gooey_macros::Widget;
use gooey_reactor::{Dynamic, Reactor, Scope, ScopeGuard};
Expand Down Expand Up @@ -568,7 +569,9 @@ where
style: Dynamic<Style>,
context: &F::Context,
) -> F::Instance {
let Some(transmogrifier) = self.by_name.get(&widget.name()) else { unreachable!("{} not registered", widget.name()) };
let Some(transmogrifier) = self.by_name.get(&widget.name()) else {
unreachable!("{} not registered", widget.name())
};
transmogrifier.0.transmogrify(widget, style, context)
}

Expand Down
166 changes: 166 additions & 0 deletions crates/gooey-core/src/window.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
use std::panic::UnwindSafe;

use figures::units::{Px, UPx};
use figures::{Point, Size};
use gooey_reactor::Dynamic;

use crate::Context;

#[derive(Default)]
#[must_use]
pub struct WindowBuilder {
attributes: WindowAttributes,
}

impl WindowBuilder {
pub fn title(mut self, title: impl Into<String>) -> Self {
self.attributes.title = title.into();
self
}

pub fn level(mut self, level: WindowLevel) -> Self {
self.attributes.window_level = level;
self
}

pub fn location(mut self, location: Point<Px>) -> Self {
self.attributes.location = Some(location);
self
}

pub fn resizable(mut self, resizable: bool) -> Self {
self.attributes.resizable = resizable;
self
}

pub fn inner_size(mut self, size: Size<UPx>) -> Self {
self.attributes.inner_size = Some(size);
self
}

pub fn create<Widget, Initializer>(self, init: Initializer) -> NewWindow<Widget>
where
Initializer: FnOnce(&Context, &Window) -> Widget + Send + UnwindSafe + 'static,
{
NewWindow {
attributes: self.attributes,
init: Box::new(init),
}
}
}

#[allow(clippy::struct_excessive_bools)]
pub struct WindowAttributes {
pub inner_size: Option<Size<UPx>>,
pub min_inner_size: Option<Size<UPx>>,
pub max_inner_size: Option<Size<UPx>>,
pub location: Option<Point<Px>>,
pub resizable: bool,
pub enabled_buttons: WindowButtons,
pub title: String,
// pub fullscreen: Option<Fullscreen>,
pub maximized: bool,
pub visible: bool,
pub transparent: bool,
pub decorations: bool,
// pub window_icon: Option<Icon>,
// pub preferred_theme: Option<Theme>,
pub resize_increments: Option<Size<UPx>>,
pub content_protected: bool,
pub window_level: WindowLevel,
// pub parent_window: Option<Window<ParentWindowEvent>>,
pub active: bool,
}

impl Default for WindowAttributes {
fn default() -> Self {
WindowAttributes {
inner_size: None,
min_inner_size: None,
max_inner_size: None,
location: None,
resizable: true,
enabled_buttons: WindowButtons::all(),
title: "Gooey".to_owned(),
maximized: false,
// fullscreen: None,
visible: true,
transparent: false,
decorations: true,
window_level: WindowLevel::default(),
// window_icon: None,
// preferred_theme: None,
resize_increments: None,
content_protected: false,
// parent_window: None,
active: true,
}
}
}

#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
pub enum WindowLevel {
/// The window will always be below normal windows.
///
/// This is useful for a widget-based app.
AlwaysOnBottom,
/// The default.
#[default]
Normal,
/// The window will always be on top of normal windows.
AlwaysOnTop,
}

#[derive(Clone, Copy, Eq, PartialEq)]
pub struct WindowButtons(u8);

impl WindowButtons {
pub const CLOSE: Self = Self(1 << 0);
pub const MAXIMIZE: Self = Self(1 << 2);
pub const MINIMIZE: Self = Self(1 << 1);

#[must_use]
pub const fn all() -> Self {
Self(Self::CLOSE.0 | Self::MAXIMIZE.0 | Self::MINIMIZE.0)
}

#[must_use]
pub const fn maximize(&self) -> bool {
self.0 & Self::MAXIMIZE.0 != 0
}

#[must_use]
pub const fn minimize(&self) -> bool {
self.0 & Self::MINIMIZE.0 != 0
}

#[must_use]
pub const fn close(&self) -> bool {
self.0 & Self::CLOSE.0 != 0
}
}

pub type WindowInitializer<Widget> =
Box<dyn FnOnce(&crate::Context, &Window) -> Widget + std::panic::UnwindSafe + Send>;

pub struct NewWindow<Widget> {
pub attributes: WindowAttributes,
pub init: WindowInitializer<Widget>,
}

pub struct Window {
pub inner_size: Dynamic<Size<UPx>>,
pub location: Dynamic<Point<Px>>,
pub title: Dynamic<String>,
}

impl Window {
#[must_use]
pub fn new(attrs: WindowAttributes, cx: &Context) -> Self {
Self {
inner_size: cx.new_dynamic(attrs.inner_size.unwrap_or_default()),
location: cx.new_dynamic(attrs.location.unwrap_or_default()),
title: cx.new_dynamic(attrs.title),
}
}
}
Loading

0 comments on commit 14ebcde

Please sign in to comment.