From e4835b9efaf2fb15eb54b8b0e2fb7f81f9b64668 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Wed, 20 Nov 2024 15:47:27 +0100 Subject: [PATCH] working render --- src/app.c | 48 ++++-------------------------------- src/app.rs | 67 +++++++++++++++++++++++++++------------------------ src/lib.rs | 4 +-- src/ui/mod.rs | 34 +++++++++++++------------- src/utils.rs | 4 +-- 5 files changed, 62 insertions(+), 95 deletions(-) diff --git a/src/app.c b/src/app.c index 21ed5b9..50a5475 100644 --- a/src/app.c +++ b/src/app.c @@ -4,15 +4,8 @@ #include #include -typedef struct -{ - uint32_t* state; - void* element; -} EventArgs; - -extern void render(void* element, uint32_t state); -extern void event(void* element, uint32_t* state); -extern void init_event(void* element, uint32_t* state); +extern boolean_t render(void* element); +extern void *event_loop(void* element); void sleep_ms(long milliseconds) { @@ -22,49 +15,18 @@ void sleep_ms(long milliseconds) nanosleep(&ts, NULL); } -void *event_checker(void *args) -{ - EventArgs* event_args = (EventArgs*)args; - init_event(event_args->element, event_args->state); - while (1) { - if (event_args->state == 0) { return NULL; } - event(event_args->element, event_args->state); - } - return NULL; -} - -void *command_checker(void *args) -{ - EventArgs* event_args = (EventArgs*)args; - init_event(event_args->element, event_args->state); - while (1) { - if (event_args->state == 0) { return NULL; } - event(event_args->element, event_args->state); - } - return NULL; -} - boolean_t c_run(void* element) { pthread_t thread; - uint32_t state = 3; - EventArgs event_args = { .element = element, .state = &state }; - if (pthread_create(&thread, NULL, event_checker, &event_args) != 0) + if (pthread_create(&thread, NULL, event_loop, element) != 0) { perror("Failed to create thread"); } - while (1) + while (render(element)) { - if (state == 0) { - free(element); - return 0; - } else if (state == 1) { - free(element); - return 1; - } - render(element, state); sleep_ms(20); } + return 0; } \ No newline at end of file diff --git a/src/app.rs b/src/app.rs index e71a09b..a535f9c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,52 +1,55 @@ -use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; +use crossterm::{ + event::Event, + terminal::{disable_raw_mode, enable_raw_mode}, +}; use crate::{ utils::{clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor}, - Element, State, StateChanger, + Element, StateChanger, }; -use std::ffi::c_void; +use std::{ffi::c_void, ptr::null}; extern "C" { fn c_run(element: *mut c_void) -> bool; } #[no_mangle] -pub extern "C" fn render(ptr: *mut c_void, state: u32) { - let element = unsafe { - assert!(!ptr.is_null(), "Pointer is null"); - &mut *(ptr as *mut Element) - }; +extern "C" fn render(ptr: *mut c_void) -> bool { + if ptr.is_null() { + return false; + } + let element = unsafe { &mut *(ptr as *mut Element) }; let (width, height) = get_term_size(); let mut frame: Vec = create_frame(width, height); - render_to_frame(State::from_u32(state), width, &mut frame, element); + render_to_frame(true, width, &mut frame, element); clear(); print!("{}", frame.join("")); flush(); + true } #[no_mangle] -pub extern "C" fn event(ptr: *mut c_void, state: *mut u32) { - let event = crossterm::event::read().unwrap(); - let element = unsafe { - assert!(!ptr.is_null(), "Pointer is null"); - &mut *(ptr as *mut Element) - }; +extern "C" fn event_loop(ptr: *mut c_void) -> *const c_void { + if ptr.is_null() { + return null() as *const c_void; + } + let element = unsafe { &mut *(ptr as *mut Element) }; + let (width, height) = get_term_size(); + element.update_data(width, height); + loop { + if ptr.is_null() { + break; + } + event(element, crossterm::event::read().unwrap()) + } + null() as *const c_void +} + +fn event(element: &mut Element, event: Event) { if let crossterm::event::Event::Resize(width, height) = event { element.update_data(width as usize, height as usize); } - element.event(event, &StateChanger(state)); -} - -#[no_mangle] -pub extern "C" fn init_event(ptr: *mut c_void, state: *mut u32) { - let event = crossterm::event::Event::FocusGained; - let element = unsafe { - assert!(!ptr.is_null(), "Pointer is null"); - &mut *(ptr as *mut Element) - }; - let (width, height) = get_term_size(); - element.update_data(width, height); - element.event(event, &StateChanger(state)); + element.event(event, &StateChanger(&mut 0)); } pub fn run(element: &mut Element) -> bool { @@ -55,9 +58,11 @@ pub fn run(element: &mut Element) -> bool { clear(); unsafe { let c = c_run(element as *mut Element as *mut c_void); - show_cursor(); - disable_raw_mode().unwrap(); - clear(); + if !c { + show_cursor(); + disable_raw_mode().unwrap(); + clear(); + } return c; } } diff --git a/src/lib.rs b/src/lib.rs index e293f0d..d15e979 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,8 +94,8 @@ pub trait ElementCore: Send + Sync { } pub trait Component: ElementCore + std::fmt::Debug { - fn render(&self, state: State) -> String { - _ = state; + fn render(&self, focused: bool) -> String { + _ = focused; String::new() } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index e645ee9..8c93d54 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -29,7 +29,7 @@ use osui_element::{elem_fn, element}; pub struct Text {} impl Component for Text<'_> { - fn render(&self, _: crate::State) -> String { + fn render(&self, _: bool) -> String { if let Children::Text(text) = &self.children { text.clone() } else { @@ -66,21 +66,17 @@ pub struct Div { } impl Component for Div<'_> { - fn render(&self, state: State) -> String { + fn render(&self, focused: bool) -> String { let mut frame = crate::utils::create_frame(self.width.get_value(), self.height.get_value()); if let Children::Children(children, child) = &self.children { for (i, elem) in children.iter().enumerate() { - if i == *child { - crate::utils::render_to_frame(state, self.width.get_value(), &mut frame, elem); - } else { - crate::utils::render_to_frame( - crate::State::Normal, - self.width.get_value(), - &mut frame, - elem, - ); - } + crate::utils::render_to_frame( + focused && i == *child, + self.width.get_value(), + &mut frame, + elem, + ); } } @@ -142,14 +138,18 @@ impl Component for Div<'_> { #[derive(Default, Debug)] pub struct Button { pub on_click: Handler>, + pub state: &'a str, } impl Component for Button<'_> { - fn render(&self, state: State) -> String { - match state { - State::Custom(_) => self.style.write("click", &self.children.get_text()), - State::Hover => self.style.write("hover", &self.children.get_text()), - _ => self.style.write("", &self.children.get_text()), + fn render(&self, focused: bool) -> String { + if self.state == "click" { + return self.style.write("click", &self.children.get_text()); + } + if focused { + self.style.write("hover", &self.children.get_text()) + } else { + self.style.write("", &self.children.get_text()) } } diff --git a/src/utils.rs b/src/utils.rs index becd5f6..388cf13 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -87,13 +87,13 @@ fn merge_line(frame_: &str, line_: &str, x: usize) -> String { /// Render to a frame pub fn render_to_frame( - state: crate::State, + focused: bool, width: usize, frame: &mut Vec, element: &Element, ) { let data = element.get_data(); - for (i, line) in element.render(state).split('\n').enumerate() { + for (i, line) in element.render(focused).split('\n').enumerate() { if (data.1 + i) < frame.len() { let frame_line = frame.get_mut(data.1 + i).unwrap(); match data.0 {