working render

This commit is contained in:
2024-11-20 15:47:27 +01:00
parent e55606b9cf
commit e4835b9efa
5 changed files with 62 additions and 95 deletions
+5 -43
View File
@@ -4,15 +4,8 @@
#include <pthread.h>
#include <time.h>
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;
}
+36 -31
View File
@@ -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<String> = 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;
}
}
+2 -2
View File
@@ -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()
}
+17 -17
View File
@@ -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<Button<'a>>,
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())
}
}
+2 -2
View File
@@ -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<String>,
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 {