Early UI work.

This commit is contained in:
2026-03-20 16:46:18 -04:00
parent 9ab1167fef
commit 39ede248cf
15 changed files with 3560 additions and 1 deletions

235
lib/ui/src/window.rs Normal file
View File

@@ -0,0 +1,235 @@
//! Common window model types.
use crate::scene::UiSize;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WindowId(u64);
impl WindowId {
pub const fn from_raw(raw: u64) -> Self {
Self(raw)
}
pub const fn raw(self) -> u64 {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum DecorationMode {
Auto,
Server,
Client,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum WindowLifecycle {
LogicalClosed,
Opening,
AwaitingInitialConfigure,
OpenHidden,
OpenVisible,
Closing,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct WindowConfigured {
pub actual_inner_size: UiSize,
pub scale_factor: f32,
pub visible: bool,
pub maximized: bool,
pub fullscreen: bool,
}
#[derive(Clone, Debug, PartialEq)]
pub struct WindowSpec {
pub key: Option<String>,
pub title: String,
pub app_id: Option<String>,
pub open: bool,
pub visible: bool,
pub requested_inner_size: Option<UiSize>,
pub min_inner_size: Option<UiSize>,
pub max_inner_size: Option<UiSize>,
pub decorations: DecorationMode,
pub maximized: bool,
pub fullscreen: bool,
pub resizable: bool,
}
impl WindowSpec {
pub fn new(title: impl Into<String>) -> Self {
Self {
key: None,
title: title.into(),
app_id: None,
open: true,
visible: true,
requested_inner_size: None,
min_inner_size: None,
max_inner_size: None,
decorations: DecorationMode::Auto,
maximized: false,
fullscreen: false,
resizable: true,
}
}
pub fn key(mut self, key: impl Into<String>) -> Self {
self.key = Some(key.into());
self
}
pub fn app_id(mut self, app_id: impl Into<String>) -> Self {
self.app_id = Some(app_id.into());
self
}
pub fn open(mut self, open: bool) -> Self {
self.open = open;
self
}
pub fn visible(mut self, visible: bool) -> Self {
self.visible = visible;
self
}
pub fn requested_inner_size(mut self, size: UiSize) -> Self {
self.requested_inner_size = Some(size);
self
}
pub fn min_inner_size(mut self, size: UiSize) -> Self {
self.min_inner_size = Some(size);
self
}
pub fn max_inner_size(mut self, size: UiSize) -> Self {
self.max_inner_size = Some(size);
self
}
pub fn decorations(mut self, decorations: DecorationMode) -> Self {
self.decorations = decorations;
self
}
pub fn maximized(mut self, maximized: bool) -> Self {
self.maximized = maximized;
self
}
pub fn fullscreen(mut self, fullscreen: bool) -> Self {
self.fullscreen = fullscreen;
self
}
pub fn resizable(mut self, resizable: bool) -> Self {
self.resizable = resizable;
self
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct WindowUpdate {
pub title: Option<String>,
pub open: Option<bool>,
pub visible: Option<bool>,
pub requested_inner_size: Option<Option<UiSize>>,
pub min_inner_size: Option<Option<UiSize>>,
pub max_inner_size: Option<Option<UiSize>>,
pub decorations: Option<DecorationMode>,
pub maximized: Option<bool>,
pub fullscreen: Option<bool>,
pub resizable: Option<bool>,
}
impl WindowUpdate {
pub fn new() -> Self {
Self::default()
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.title = Some(title.into());
self
}
pub fn open(mut self, open: bool) -> Self {
self.open = Some(open);
self
}
pub fn visible(mut self, visible: bool) -> Self {
self.visible = Some(visible);
self
}
pub fn requested_inner_size(mut self, size: Option<UiSize>) -> Self {
self.requested_inner_size = Some(size);
self
}
pub fn min_inner_size(mut self, size: Option<UiSize>) -> Self {
self.min_inner_size = Some(size);
self
}
pub fn max_inner_size(mut self, size: Option<UiSize>) -> Self {
self.max_inner_size = Some(size);
self
}
pub fn decorations(mut self, decorations: DecorationMode) -> Self {
self.decorations = Some(decorations);
self
}
pub fn maximized(mut self, maximized: bool) -> Self {
self.maximized = Some(maximized);
self
}
pub fn fullscreen(mut self, fullscreen: bool) -> Self {
self.fullscreen = Some(fullscreen);
self
}
pub fn resizable(mut self, resizable: bool) -> Self {
self.resizable = Some(resizable);
self
}
pub(crate) fn apply_to(&self, spec: &mut WindowSpec) {
if let Some(title) = &self.title {
spec.title = title.clone();
}
if let Some(open) = self.open {
spec.open = open;
}
if let Some(visible) = self.visible {
spec.visible = visible;
}
if let Some(requested_inner_size) = self.requested_inner_size {
spec.requested_inner_size = requested_inner_size;
}
if let Some(min_inner_size) = self.min_inner_size {
spec.min_inner_size = min_inner_size;
}
if let Some(max_inner_size) = self.max_inner_size {
spec.max_inner_size = max_inner_size;
}
if let Some(decorations) = self.decorations {
spec.decorations = decorations;
}
if let Some(maximized) = self.maximized {
spec.maximized = maximized;
}
if let Some(fullscreen) = self.fullscreen {
spec.fullscreen = fullscreen;
}
if let Some(resizable) = self.resizable {
spec.resizable = resizable;
}
}
}