engine
This commit is contained in:
+1
-21
@@ -1,21 +1 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# RustRover
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
/target
|
||||
|
||||
Generated
+300
@@ -0,0 +1,300 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"rustix",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "osmium-engine"
|
||||
version = "0.0.1-alpha.0"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "osmium-engine"
|
||||
version = "0.0.1-alpha.0"
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
description = "A TUI library for advanced uis"
|
||||
repository = "https://github.com/osui-rs/engine"
|
||||
homepage = "https://osui.netlify.app"
|
||||
documentation = "https://osui.netlify.app/docs/"
|
||||
|
||||
[lib]
|
||||
name = "osmium_engine"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "osmium_engine"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
crossterm = "0.28.1"
|
||||
@@ -0,0 +1,13 @@
|
||||
use crate::Element;
|
||||
|
||||
impl Element for &str {
|
||||
fn render(&self) -> String {
|
||||
self.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Element for String {
|
||||
fn render(&self) -> String {
|
||||
self.to_owned()
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
pub mod elements;
|
||||
pub mod utils;
|
||||
|
||||
pub use std::io::Result;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::{utils::init, Props, Result, Ui};
|
||||
}
|
||||
|
||||
// Traits
|
||||
|
||||
pub trait Framing {
|
||||
fn draw(&mut self, element: &dyn Element, props: &Props);
|
||||
}
|
||||
|
||||
pub trait Element {
|
||||
fn render(&self) -> String;
|
||||
}
|
||||
|
||||
// Types
|
||||
pub type Ui = Arc<dyn Fn(&mut dyn Framing)>;
|
||||
|
||||
pub enum Position {
|
||||
Num(u16),
|
||||
Center,
|
||||
}
|
||||
|
||||
pub struct Props(Position, Position);
|
||||
|
||||
/// Represents the console state, containing a frame for rendering and a mouse capture flag.
|
||||
pub struct Console {
|
||||
mouse: bool,
|
||||
width: u16,
|
||||
height: u16,
|
||||
}
|
||||
|
||||
impl Position {
|
||||
pub fn get(&self, written: u16, frame: u16) -> u16 {
|
||||
match self {
|
||||
Self::Center => (frame - written) / 2,
|
||||
Self::Num(n) => *n,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Props {
|
||||
pub fn new(x: u16, y: u16) -> Self {
|
||||
Self(Position::Num(x), Position::Num(y))
|
||||
}
|
||||
|
||||
pub fn center() -> Self {
|
||||
Self(Position::Center, Position::Center)
|
||||
}
|
||||
|
||||
pub fn center_horizontal() -> Self {
|
||||
Self(Position::Center, Position::Num(0))
|
||||
}
|
||||
|
||||
pub fn center_vertical() -> Self {
|
||||
Self(Position::Num(0), Position::Center)
|
||||
}
|
||||
}
|
||||
|
||||
impl Framing for Console {
|
||||
fn draw(&mut self, element: &dyn Element, props: &Props) {
|
||||
let written = element.render();
|
||||
|
||||
let (written_width, written_height) = utils::str_size(&written);
|
||||
|
||||
let (x, y) = (
|
||||
props.0.get(written_width, self.width),
|
||||
props.1.get(written_height, self.height),
|
||||
);
|
||||
|
||||
for (i, line) in written.lines().enumerate() {
|
||||
println!("\x1b[{};{}H{}", y as usize + i + 1, x + 1, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Console {
|
||||
pub fn render(&mut self, ui: Ui) -> Result<()> {
|
||||
utils::clear()?;
|
||||
(self.width, self.height) = crossterm::terminal::size()?;
|
||||
ui(self);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn close(self) -> Result<()> {
|
||||
if self.mouse {
|
||||
crossterm::execute!(std::io::stdout(), crossterm::event::DisableMouseCapture)?;
|
||||
}
|
||||
crossterm::terminal::disable_raw_mode()?;
|
||||
utils::show_cursor()?;
|
||||
utils::clear()
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use osmium_engine::prelude::*;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut console = init(false)?;
|
||||
|
||||
console.render(app())?;
|
||||
|
||||
crossterm::event::read()?;
|
||||
|
||||
console.close()
|
||||
}
|
||||
|
||||
pub fn app() -> Ui {
|
||||
Arc::new(|frame| {
|
||||
frame.draw(&"Hello, World", &Props::center());
|
||||
})
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
//! The `utils` module provides utility functions for terminal manipulation
|
||||
//! and string operations, designed to enhance terminal-based applications.
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
/// Clears the terminal screen and moves the cursor to the top-left corner.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `crate::Result<()>` indicating whether the operation succeeded.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// utils::clear().unwrap();
|
||||
/// ```
|
||||
pub fn clear() -> crate::Result<()> {
|
||||
print!("\x1B[2J\x1B[H");
|
||||
std::io::stdout().flush()
|
||||
}
|
||||
|
||||
/// Hides the terminal cursor.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `crate::Result<()>` indicating whether the operation succeeded.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// utils::hide_cursor().unwrap();
|
||||
/// ```
|
||||
pub fn hide_cursor() -> crate::Result<()> {
|
||||
print!("\x1b[?25l");
|
||||
std::io::stdout().flush()
|
||||
}
|
||||
|
||||
/// Shows the terminal cursor.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `crate::Result<()>` indicating whether the operation succeeded.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// utils::show_cursor().unwrap();
|
||||
/// ```
|
||||
pub fn show_cursor() -> crate::Result<()> {
|
||||
print!("\x1B[?25h");
|
||||
std::io::stdout().flush()
|
||||
}
|
||||
|
||||
/// Flushes the terminal's stdout buffer.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `crate::Result<()>` indicating whether the operation succeeded.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// utils::flush().unwrap();
|
||||
/// ```
|
||||
pub fn flush() -> crate::Result<()> {
|
||||
std::io::stdout().flush()
|
||||
}
|
||||
|
||||
/// Calculates the width and height of a string when rendered in a terminal.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `s`: The input string.
|
||||
///
|
||||
/// # Returns
|
||||
/// A tuple `(u16, u16)` where:
|
||||
/// - The first value is the maximum width of the string in characters.
|
||||
/// - The second value is the height of the string in lines.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// let (width, height) = utils::str_size("Hello\nWorld!");
|
||||
/// assert_eq!((5, 2), (width, height));
|
||||
/// ```
|
||||
pub fn str_size(s: &str) -> (u16, u16) {
|
||||
let mut height = 1;
|
||||
let mut max_width = 0;
|
||||
let mut current_width = 0;
|
||||
|
||||
for b in s.bytes() {
|
||||
if b == b'\n' {
|
||||
height += 1;
|
||||
max_width = max_width.max(current_width);
|
||||
current_width = 0;
|
||||
} else {
|
||||
current_width += 1;
|
||||
}
|
||||
}
|
||||
|
||||
max_width = max_width.max(current_width);
|
||||
|
||||
(max_width, height)
|
||||
}
|
||||
|
||||
/// Initializes the console with raw mode enabled and optionally mouse capture.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `mouse` - A boolean flag indicating whether to enable mouse capture.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `Console` instance wrapped in a `Result`.
|
||||
pub fn init(mouse: bool) -> crate::Result<crate::Console> {
|
||||
crossterm::terminal::enable_raw_mode()?;
|
||||
clear()?;
|
||||
hide_cursor()?;
|
||||
if mouse {
|
||||
crossterm::execute!(std::io::stdout(), crossterm::event::EnableMouseCapture)?;
|
||||
}
|
||||
let (width, height) = crossterm::terminal::size()?;
|
||||
Ok(crate::Console {
|
||||
width,
|
||||
height,
|
||||
mouse,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user