From 8fa9506df024abbc16df40eda8eb7ff94db796df Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sun, 19 Jan 2025 23:16:52 +0100 Subject: [PATCH] OSUI v0.0.9 --- blog/authors.yml | 7 ++ blog/osui-rewrite.md | 23 ++++++ docs/engine.md | 40 +++++++++++ docs/index.md | 45 ++++++------ docs/references/a_rsx.md | 129 ---------------------------------- docs/references/b_handler.md | 48 ------------- docs/references/component.md | 24 ------- docs/references/css.md | 39 ---------- docs/references/d_style.md | 20 ------ docs/references/e_document.md | 28 -------- docs/references/f_element.md | 54 -------------- docs/references/g_writer.md | 11 --- docusaurus.config.ts | 117 +++++++++++++++--------------- 13 files changed, 151 insertions(+), 434 deletions(-) create mode 100644 blog/osui-rewrite.md create mode 100644 docs/engine.md delete mode 100644 docs/references/a_rsx.md delete mode 100644 docs/references/b_handler.md delete mode 100644 docs/references/component.md delete mode 100644 docs/references/css.md delete mode 100644 docs/references/d_style.md delete mode 100644 docs/references/e_document.md delete mode 100644 docs/references/f_element.md delete mode 100644 docs/references/g_writer.md diff --git a/blog/authors.yml b/blog/authors.yml index e69de29..a93b500 100644 --- a/blog/authors.yml +++ b/blog/authors.yml @@ -0,0 +1,7 @@ +kleo-dev: + name: Leo + title: Creator of OSUI + url: https://github.com/kleo-dev + image_url: https://github.com/kleo-dev.png + socials: + github: kleo-dev diff --git a/blog/osui-rewrite.md b/blog/osui-rewrite.md new file mode 100644 index 0000000..0305cf4 --- /dev/null +++ b/blog/osui-rewrite.md @@ -0,0 +1,23 @@ +--- +title: Releasing OSUI v0.0.9 +description: A new upcoming version of OSUI will come out. Let's re-write it. +slug: welcome-docusaurus-v2 +authors: + - kleo-dev +--- + +Why would i bother re-writing a TUI library? Well there was a LOT of things wrong with the old version of OSUI. It had bugs and lacks performance. v0.0.9 fixes all of those and hopefully we can achieve a better future for OSUI. With that being said. Let's get into what i plan on doing. + +## ⚙️ OSUI Engine +OSUI v0.0.9 Comes with a engine that works under the hood and can be manipulated to match your needs. Here are a few examples: +- Game engine +- Fluid simulation +- Velocity +This may seem like a gimmick but it's essential to provide features only when needed and prioritize performance to extend reliability. [Read more](/docs/next/engine) + +## ⚡️ Improvements +- 📌 Reliable +- 🌿 Minimal +- 🚀 Fast +- 📚 Better documentation (soon) +- 🧑🏻‍💻 Better codebase \ No newline at end of file diff --git a/docs/engine.md b/docs/engine.md new file mode 100644 index 0000000..213ced7 --- /dev/null +++ b/docs/engine.md @@ -0,0 +1,40 @@ +--- +title: Engine +slug: /engine +--- + +The OSUI engine is what goes on under the hood. You might need this on special ocasions (Game engine, Custom animation, Physics, etc) because it's easier to manipulate. Here's an example of an element moving with a velocity of 50: + +```rust +use osui::prelude::*; + +fn main() -> Result<()> { + let mut con = console::init(true)?; + let velocity = 50; + let mut position = use_state(0); + + loop { + con.draw(app(*position), None)?; + std::thread::sleep(std::time::Duration::from_millis(1000 / velocity)); + position += 1; + if position + 13 > con.size().0 { + break; + } + } + + con.end() +} + +pub fn app(pos: u16) -> Element { + std::sync::Arc::new(move |frame, _event| -> Result<()> { + frame.draw( + &"Hello, World!", + Area { + x: Pos::Num(pos), + ..Default::default() + }, + )?; + Ok(()) + }) +} +``` diff --git a/docs/index.md b/docs/index.md index b88e2d6..a22d6f0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,48 +4,51 @@ slug: / --- ## Installation + On a cargo project run + ```bash cargo add osui ``` -## Simple app +## Hello world + ```rust title='src/main.rs' use osui::prelude::*; -fn main() { - launch!(App); +fn main() -> Result<()> { + let mut con = console::init(true)?; + + con.run(app())?; + + con.end() } -#[component] -fn App() -> Element { +pub fn app() -> Element { rsx! { - text { "Hello, World!" } + "Hello, World!" } } ``` -## A slightly more advanced app (counter) -This app uses state management and a function using the state as a dependent +## Counter + ```rust title='src/main.rs' use osui::prelude::*; -fn main() { - launch!(App); +fn main() -> Result<()> { + let mut con = console::init(true)?; + + con.run(app())?; + + con.end() } -#[component] -fn App() -> Element { - let count = State::new(0); +pub fn app() -> Element { + let count = use_state(0); rsx! { - button { - on_click: fn(_, _, _) @count { - count += 1; - }, - - "The current count is: {count}" - } + button { on_click: move |_| count+=1, "{count}" } } } -``` \ No newline at end of file +``` diff --git a/docs/references/a_rsx.md b/docs/references/a_rsx.md deleted file mode 100644 index b3a1b19..0000000 --- a/docs/references/a_rsx.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: RSX ---- - -This macro is the recommended way to describe a ui, it is a div that holds multiple elements -```rust -#[component] -fn App() -> Element { - rsx! { - button { "click me" } - text { "This is some text" } - } -} -``` - -> :::info `rsx!` is really just a div, so you can just do something like -> ```rust -> rsx! { -> id: "root", class: "root", -> -> button { "click me" } -> text { "This is some text" } -> } -> ``` - -## Child values -If you want to add more children to values then just simply express it like a `rsx!` -```rust -let x = 69; - -rsx! { - div { - text { "the number is {x}, Nice!" } - } -} -``` - -## Formatted text -```rust -let x = 69; - -rsx! { - text { "the number is {x}, Nice!" } -} -``` -> :::info You can also do expressions after the string -```rust -text { "the number is {}, Nice!", x } -``` - -## For loops -```rust -rsx! { - for (i in 0..5) { // () are required - text { "{i}" } - } -} -``` - -## Attribute -You can change the element's struct fields by just providing some attributes before the children -```rust -rsx! { - text { class: "my_text" } -} -``` - -## Handler functions -Instead of closures which are tricky to work with on structs, We use `Handler`, It's basically a closure wrapped with a `Arc>` -```rust -rsx! { - button { - on_click: fn(btn: &mut Button, event, document) { - // do something - } - } -} -``` - -## Handler functions (with dependents) -If you have a `State` and want to use it, you have to put a @ before the code block like this -```rust -let count = State::new(); - -rsx! { - button { - on_click: fn(btn: &mut Button, event, document) @count { - let count = count.use_state(); // locks count so it can be used - }, - "Current count: {count}" - } -} -``` -> :::info you can add multiple decedents by separating them via `,` like: @var1, var2, var3 - -## Static text -If your text doesn't use variables that will change you can put `static` right before the text to signal that it's static. -```rust -let count = 69; // count won't change since it's not mutable - -rsx! { - text { - static "Current count: {count}" - } -} -``` - -## Instructions -Add an instruction by putting a `@` before it, like this: -```rust -rsx! { - @SetStyle(css! { // the SetStyle instruction - "title": { - color: Green, - } - }) - - text { class: "title", static "Hello world!" } -} -``` - -# Ghost elements -With a `div` you can use tab (or shift+tab) to go through components, But sometimes an element doesn't really do anything, So to skip over the element you can use the ghost syntax `%`. This makes it so that the element is not selectable. -```rust -rsx! { - %text { "This is a ghost title!!!!" } - - button { "Click me!" } -} \ No newline at end of file diff --git a/docs/references/b_handler.md b/docs/references/b_handler.md deleted file mode 100644 index 3b513d6..0000000 --- a/docs/references/b_handler.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: Handler ---- - -A `Handler` is a closure wrapper. Due to how closures work, they aren't the best to work with on structs (in this case: elements). So to fix this we use a `Handler` which is a wrapper for the closure, Then you can safely clone and use it without any problems (in which a normal closure would fail at) - -## Examples -```rust -Handler::new(|btn: &mut Button, event, document| { - // do something -}) -``` -### Recommended way -```rust -rsx! { - button { - // No need for Handler::new - on_click: fn(btn: &mut Button, event, document) { - // do something - } - } -} -``` -### With dependents -If you have a `State` and want to use it in a `fn()`, Pub a @ before the code block like this -```rust -#[component] -pub fn App() -> Element { - let count = State::new(0); - rsx! { - button { - on_click: fn(_, _, _) @count { - count += 1; - }, - "The current count is: {count}" - } - } -} -``` - -### How to call a handler -```rust -my_handler.clone().call(); -``` - -> :::info you can add multiple decedents by separating them via `,` like: @var1, var2, var3 - -> :::info `fn() {}` is a part of the OSUI macro `rsx!`. In rust you would normally use `|| {}` \ No newline at end of file diff --git a/docs/references/component.md b/docs/references/component.md deleted file mode 100644 index ff04453..0000000 --- a/docs/references/component.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Component ---- - -A `Component` is a function but in the backend it's a struct. It's a struct because of named parameters. It can be defiend using the `#[component]` attribute. -```rust -#[component] -pub fn App() -> Element { - rsx! { - User { name: "leo", age: 15 } - } -} - -#[component] -pub fn User<'a>(name: &'a str, age: u8) { - rsx! { - text { static "Welcome {}! You are {} years old!", self.name, self.age } - } -} -``` - -If you're wondering why `User` doesn't have a return type, it's because the `#[component]` attribute sets it automatically, You can also use a custom return type. - -The `text` is static because self.name is a reference, dynamic text needs the lifetimes to be `'static`. \ No newline at end of file diff --git a/docs/references/css.md b/docs/references/css.md deleted file mode 100644 index 11d8de5..0000000 --- a/docs/references/css.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: CSS ---- - -Along with the `Css` type, This macro provides styling for multiple elements by their class name. - -## Example -In this case we will make a button with the classname `my_btn`. And set `styling` -```rust -#[component] -fn App() -> Element { - rsx! { - @SetStyle(css! { - blue-outline { - outline: true, - outline_color: Blue, - } - - red { - color: Red, - } - - green-hover: "hover" { - color: Green, - } - }) - - button { class: "red blue-outline green-hover", "Click me!" } - } -} -``` - -## `hover` -The `hover` state is on every element but only if it's focused/hovered. -```rust -"my_btn": "hover" { - color: Green, -} -``` \ No newline at end of file diff --git a/docs/references/d_style.md b/docs/references/d_style.md deleted file mode 100644 index b65c1b1..0000000 --- a/docs/references/d_style.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Style ---- - -Like `css!`, `style!` is a way to style a element. But unlike `css!`, `style!` is only meant to style a single element - -```rust -rsx! { - button { - style: style! { - color: Red, - "clicked" { // when the button state is 'clicked' - color: Blue, - } - }, - - "click me!" - } -} -``` \ No newline at end of file diff --git a/docs/references/e_document.md b/docs/references/e_document.md deleted file mode 100644 index f98d72e..0000000 --- a/docs/references/e_document.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Document ---- - -The `Document` holds the root element and it renders and passes events to the `Element`. It's important for updating the UI. - -## Example -```rust -fn(_, _, document) { - if let Some(my_text) = document.get_element_by_id::("my_text") { - my_text.children.set_text("Updated!"); - } -} -``` - -## Methods -### `exit()` -Exits the program -### `restart()` -Restarts the program -### `get_element_by_id(id: &str) -> Option<&mut Box>` -Retrieves a mutable reference to a boxed element of type T by its string identifier, returning None if no such element exists. -> :::info Please make sure that the type of the element is correctly matched to the element of that id -### `get_element_by_id_raw(id: &str) -> Option<&mut Element>` -> :::warning Not recommended to use this function, Use `get_element_by_id` instead -Retrieves a mutable reference to a boxed element by its string identifier, returning None if no such element exists -### `render()` -Renders/reloads the screen, useful when a element updates \ No newline at end of file diff --git a/docs/references/f_element.md b/docs/references/f_element.md deleted file mode 100644 index 8bdbc55..0000000 --- a/docs/references/f_element.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Element ---- - -A element is a very important part of a UI library, It's what makes it possible. - -`Element` is a type alias of `Box`. It makes the code look cleaner. - -# ElementWidget -`ElementWidget` is a trait that defines the Elements and it's rendering / event updates. - -## Methods -### `render(&self, focused: bool) -> Option` -- **required** -- This function renders the element - -### `event(&mut self, event: Event, document: &Document)` -- **optional** -- This function updates the element when there is a event - -### `event(&mut self, document: &mut Document)` -- **optional** -- This function runs when the app first runs. It helps with element initialization after the `rsx!` stage. - - -# ElementCore -`ElementCore` is a trait that will automatically be implemented by the `osui_element::element` proc-macro. All of it's functions are used by OSUI. - -## `element` proc-macro -This macro adds the essential fields and functions for a `ElementCore` structure. -```rust -use osui_element::element; -#[element] -#[derive(Default, Debug)] -struct MyElement {} -``` - -## `elem_fn` proc-macro -This macro makes a function that returns a `Box` of which T is the default of `MyElement` -```rust -use osui_element::{element, elem_fn}; -#[element] -#[elem_fn] -#[derive(Default, Debug)] -struct MyElement {} -``` - ->:::info ->You can also define a function for the element manually: ->```rust ->pub fn my_element() -> Box { -> Box::new(MyElement::default()) ->} ->``` \ No newline at end of file diff --git a/docs/references/g_writer.md b/docs/references/g_writer.md deleted file mode 100644 index b8c9af3..0000000 --- a/docs/references/g_writer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Writer ---- - -The `Writer` is what makes OSUI efficient and it's magic. `Writer` is used on the `Element::render` function. It get's access to the `Style` and gets a absolute position and ansi coloring, Then it prints and adjusts to what is being written. - -## Functions -### `write(&mut self, s: &str)` -This function simply writes s to the screen depending on the absolute positioning. -### `new_frame(&mut self) -> Frame` -This function creates a frame depending on the values. Use this you need to render elements. \ No newline at end of file diff --git a/docusaurus.config.ts b/docusaurus.config.ts index ca42722..63d423c 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,48 +1,45 @@ -import {themes as prismThemes} from 'prism-react-renderer'; -import type {Config} from '@docusaurus/types'; -import type * as Preset from '@docusaurus/preset-classic'; +import { themes as prismThemes } from "prism-react-renderer"; +import type { Config } from "@docusaurus/types"; +import type * as Preset from "@docusaurus/preset-classic"; const config: Config = { - title: 'OSUI', - - tagline: 'Style your terminal, The creative way', - favicon: 'img/favicon.ico', - url: 'https://osui.netlify.app', - baseUrl: '/', - organizationName: 'osui-rs', - projectName: 'osui', - onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', + title: "OSUI", + + tagline: "Style your terminal, The creative way", + favicon: "img/favicon.ico", + url: "https://osui.netlify.app", + baseUrl: "/", + organizationName: "osui-rs", + projectName: "osui", + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", i18n: { - defaultLocale: 'en', - locales: ['en'], + defaultLocale: "en", + locales: ["en"], }, - plugins: [require.resolve('docusaurus-lunr-search')], + plugins: [require.resolve("docusaurus-lunr-search")], presets: [ [ - 'classic', + "classic", { docs: { - sidebarPath: './sidebars.json', - editUrl: - 'https://github.com/osui-rs/docs/tree/master/', + sidebarPath: "./sidebars.json", + editUrl: "https://github.com/osui-rs/docs/tree/master/", + }, + blog: { + showReadingTime: true, + feedOptions: { + type: ["rss", "atom"], + xslt: true, + }, + editUrl: "https://github.com/osui-rs/docs/", + onInlineTags: "warn", + onInlineAuthors: "warn", + onUntruncatedBlogPosts: "warn", }, - blog: false, - // blog: { - // showReadingTime: true, - // feedOptions: { - // type: ['rss', 'atom'], - // xslt: true, - // }, - // editUrl: - // 'https://github.com/osui-rs/docs/', - // onInlineTags: 'warn', - // onInlineAuthors: 'warn', - // onUntruncatedBlogPosts: 'warn', - // }, theme: { - customCss: './src/css/custom.css', + customCss: "./src/css/custom.css", }, } satisfies Preset.Options, ], @@ -50,27 +47,27 @@ const config: Config = { themeConfig: { navbar: { - title: 'OSUI', + title: "OSUI", logo: { - alt: 'OSUI Logo', - src: 'img/osui.png', + alt: "OSUI Logo", + src: "img/osui.png", }, items: [ { - type: 'docSidebar', - sidebarId: 'docsSidebar', - position: 'left', - label: 'Docs', + type: "docSidebar", + sidebarId: "docsSidebar", + position: "left", + label: "Docs", }, - // {to: '/blog', label: 'Blog', position: 'left'}, + {to: '/blog', label: 'Blog', position: 'left'}, { - type: 'docsVersionDropdown', - position: 'left', + type: "docsVersionDropdown", + position: "left", dropdownActiveClassDisabled: true, }, { - href: 'https://github.com/osui-rs/osui/', - position: 'right', + href: "https://github.com/osui-rs/osui/", + position: "right", html: ` @@ -80,40 +77,40 @@ const config: Config = { ], }, footer: { - style: 'dark', + style: "dark", links: [ { - title: 'Docs', + title: "Docs", items: [ { - label: 'Installation', - to: '/docs/', + label: "Installation", + to: "/docs/", }, ], }, { - title: 'Community', + title: "Community", items: [ { - label: 'Discord', - href: 'https://discordapp.com/invite/jqc9dR6kBZ', + label: "Discord", + href: "https://discordapp.com/invite/jqc9dR6kBZ", }, { - label: 'GitHub', - href: 'https://github.com/osui-rs/osui/', + label: "GitHub", + href: "https://github.com/osui-rs/osui/", }, ], }, { - title: 'Resources', + title: "Resources", items: [ { - label: 'Crossterm', - href: 'https://github.com/crossterm-rs/crossterm', + label: "Crossterm", + href: "https://github.com/crossterm-rs/crossterm", }, { - label: 'Rust-lang', - href: 'https://rust-lang.org/', + label: "Rust-lang", + href: "https://rust-lang.org/", }, ], },