A => .gitignore +1 -0
A => Cargo.lock +267 -0
@@ 1,267 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "allocator-api2"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
+
+[[package]]
+name = "bitflags"
+version = "2.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
+
+[[package]]
+name = "castaway"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
+dependencies = [
+ "rustversion",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "compact_str"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab"
+dependencies = [
+ "castaway",
+ "cfg-if",
+ "itoa",
+ "rustversion",
+ "ryu",
+ "static_assertions",
+]
+
+[[package]]
+name = "either"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "foldhash"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
+
+[[package]]
+name = "hashbrown"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash",
+]
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "itertools"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+
+[[package]]
+name = "kasuari"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899"
+dependencies = [
+ "hashbrown 0.16.1",
+ "thiserror",
+]
+
+[[package]]
+name = "lru"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b6180140927ee907000b0aa540091f6ea512ead4447c92b8fc35bc72788a5a6"
+dependencies = [
+ "hashbrown 0.17.1",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "ratatui-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbb175c433c8e28a809d1f5773a2ae96e68c0ce40db865cbab1020bf33ae479c"
+dependencies = [
+ "bitflags",
+ "compact_str",
+ "hashbrown 0.17.1",
+ "itertools",
+ "kasuari",
+ "lru",
+ "strum",
+ "thiserror",
+ "unicode-segmentation",
+ "unicode-truncate",
+ "unicode-width",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
+
+[[package]]
+name = "ryu"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "strum"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd"
+dependencies = [
+ "strum_macros",
+]
+
+[[package]]
+name = "strum_macros"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
+
+[[package]]
+name = "unicode-truncate"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5"
+dependencies = [
+ "itertools",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
+
+[[package]]
+name = "wit"
+version = "0.1.0"
+dependencies = [
+ "ratatui-core",
+]
A => Cargo.toml +7 -0
@@ 1,7 @@
+[package]
+name = "wit"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+ratatui-core = "0.1.2"
A => src/error.rs +18 -0
@@ 1,18 @@
+#[derive(Debug)]
+pub enum WitError {
+ WidgetError(WidgetError),
+ CompositorError(CompositorError),
+}
+
+#[derive(Debug)]
+pub enum WidgetError {
+ SetSize,
+ AddChild,
+ SetPos,
+ SetDisplayMode,
+}
+
+#[derive(Debug)]
+pub enum CompositorError {
+
+}
A => src/lib.rs +6 -0
@@ 1,6 @@
+pub mod widgets;
+
+pub mod error;
+
+#[cfg(test)]
+mod tests;
A => src/tests.rs +0 -0
A => src/widgets/frame.rs +43 -0
@@ 1,43 @@
+use super::widget::{Widget, DisplayMode, WidgetSize, WidgetPos};
+use crate::error;
+
+pub struct Frame {
+ size: WidgetSize,
+ pos: WidgetPos,
+ display_mode: DisplayMode,
+ children: Vec<Box<dyn Widget>>,
+}
+
+impl Widget for Frame {
+ fn set_size(&mut self, new_size: WidgetSize) -> Result<(), error::WitError>{
+ self.size = new_size;
+ Ok(())
+ }
+ fn size(&self) -> WidgetSize {
+ self.size
+ }
+
+ fn add_child(&mut self, child: Box<dyn Widget>) -> Result<(), error::WitError>{
+ self.children.push(child);
+ Ok(())
+ }
+ fn children(&self) -> &[Box<dyn Widget>] {
+ self.children.as_slice()
+ }
+
+ fn set_pos(&mut self, new_pos: WidgetPos) -> Result<(), error::WitError>{
+ self.pos = new_pos;
+ Ok(())
+ }
+ fn pos(&self) -> WidgetPos {
+ self.pos
+ }
+
+ fn set_display_mode(&mut self, new_display_mode: DisplayMode) -> Result<(), error::WitError>{
+ self.display_mode = new_display_mode;
+ Ok(())
+ }
+ fn display_mode(&self) -> DisplayMode {
+ self.display_mode
+ }
+}
A => src/widgets/mod.rs +4 -0
@@ 1,4 @@
+pub mod frame;
+
+pub mod widget;
+pub use widget::*;
A => src/widgets/widget.rs +98 -0
@@ 1,98 @@
+use crate::error;
+
+pub trait Widget {
+ fn set_size(&mut self, size: WidgetSize) -> Result<(), error::WitError>;
+ fn size(&self) -> WidgetSize;
+ fn add_child(&mut self, child: Box<dyn Widget>) -> Result<(), error::WitError>;
+ fn children(&self) -> &[Box<dyn Widget>];
+ fn set_pos(&mut self, pos: WidgetPos) -> Result<(), error::WitError>;
+ fn pos(&self) -> WidgetPos;
+ fn set_display_mode(&mut self, display: DisplayMode) -> Result<(), error::WitError>;
+ fn display_mode(&self) -> DisplayMode;
+
+ fn set_static(&mut self) -> Result<(), error::WitError> { self.set_display_mode(DisplayMode::Static) }
+ fn is_static(&self) -> bool { matches!(self.display_mode(), DisplayMode::Static) }
+ fn set_floating(&mut self) -> Result<(), error::WitError> { self.set_display_mode(DisplayMode::Floating) }
+ fn is_floating(&self) -> bool { matches!(self.display_mode(), DisplayMode::Floating) }
+ fn hide(&mut self) -> Result<(), error::WitError> { self.set_display_mode(DisplayMode::Hidden) }
+ fn is_hidden(&self) -> bool { matches!(self.display_mode(), DisplayMode::Hidden) }
+}
+
+// should write some macros to make this nicer
+
+#[derive(Clone, Copy)]
+pub struct WidgetSize(WidgetSizeDimn, WidgetSizeDimn);
+
+impl WidgetSize {
+ #[inline(always)]
+ pub fn x(&self) -> WidgetSizeDimn {
+ self.0
+ }
+ #[inline(always)]
+ pub fn y(&self) -> WidgetSizeDimn {
+ self.1
+ }
+}
+
+impl From<WidgetSize> for (u16, u16) {
+ #[inline(always)]
+ fn from(size: WidgetSize) -> Self {
+ (size.0.into(), size.1.into())
+ }
+}
+
+#[derive(Clone, Copy)]
+pub enum WidgetSizeDimn {
+ Static(u16),
+ Fill,
+ Fit,
+}
+
+impl From<WidgetSizeDimn> for u16 {
+ #[inline(always)]
+ fn from(dim: WidgetSizeDimn) -> Self {
+ match dim {
+ WidgetSizeDimn::Static(x) => x,
+ WidgetSizeDimn::Fill => todo!(),
+ WidgetSizeDimn::Fit => todo!(),
+ }
+ }
+}
+
+#[derive(Clone, Copy)]
+pub struct WidgetPos(WidgetPosDimn, WidgetPosDimn);
+
+impl WidgetPos {
+ #[inline(always)]
+ pub fn x(&self) -> WidgetPosDimn {
+ self.0
+ }
+ #[inline(always)]
+ pub fn y(&self) -> WidgetPosDimn {
+ self.1
+ }
+}
+
+impl Default for WidgetPos {
+ fn default() -> WidgetPos {
+ WidgetPos(WidgetPosDimn::FloatStart, WidgetPosDimn::FloatStart)
+ }
+}
+
+#[derive(Clone, Copy)]
+pub enum WidgetPosDimn {
+ Static(u16),
+ FloatStart,
+ FloatEnd,
+}
+
+impl Default for WidgetPosDimn {
+ fn default() -> Self { Self::FloatStart }
+}
+
+#[derive(Clone, Copy)]
+pub enum DisplayMode {
+ Static,
+ Floating,
+ Hidden,
+}