working render
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user