working render
This commit is contained in:
@@ -4,15 +4,8 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
typedef struct
|
extern boolean_t render(void* element);
|
||||||
{
|
extern void *event_loop(void* element);
|
||||||
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);
|
|
||||||
|
|
||||||
void sleep_ms(long milliseconds)
|
void sleep_ms(long milliseconds)
|
||||||
{
|
{
|
||||||
@@ -22,49 +15,18 @@ void sleep_ms(long milliseconds)
|
|||||||
nanosleep(&ts, NULL);
|
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)
|
boolean_t c_run(void* element)
|
||||||
{
|
{
|
||||||
pthread_t thread;
|
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");
|
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);
|
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::{
|
use crate::{
|
||||||
utils::{clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor},
|
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" {
|
extern "C" {
|
||||||
fn c_run(element: *mut c_void) -> bool;
|
fn c_run(element: *mut c_void) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn render(ptr: *mut c_void, state: u32) {
|
extern "C" fn render(ptr: *mut c_void) -> bool {
|
||||||
let element = unsafe {
|
if ptr.is_null() {
|
||||||
assert!(!ptr.is_null(), "Pointer is null");
|
return false;
|
||||||
&mut *(ptr as *mut Element)
|
}
|
||||||
};
|
let element = unsafe { &mut *(ptr as *mut Element) };
|
||||||
let (width, height) = get_term_size();
|
let (width, height) = get_term_size();
|
||||||
let mut frame: Vec<String> = create_frame(width, height);
|
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();
|
clear();
|
||||||
print!("{}", frame.join(""));
|
print!("{}", frame.join(""));
|
||||||
flush();
|
flush();
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn event(ptr: *mut c_void, state: *mut u32) {
|
extern "C" fn event_loop(ptr: *mut c_void) -> *const c_void {
|
||||||
let event = crossterm::event::read().unwrap();
|
if ptr.is_null() {
|
||||||
let element = unsafe {
|
return null() as *const c_void;
|
||||||
assert!(!ptr.is_null(), "Pointer is null");
|
}
|
||||||
&mut *(ptr as *mut Element)
|
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 {
|
if let crossterm::event::Event::Resize(width, height) = event {
|
||||||
element.update_data(width as usize, height as usize);
|
element.update_data(width as usize, height as usize);
|
||||||
}
|
}
|
||||||
element.event(event, &StateChanger(state));
|
element.event(event, &StateChanger(&mut 0));
|
||||||
}
|
|
||||||
|
|
||||||
#[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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(element: &mut Element) -> bool {
|
pub fn run(element: &mut Element) -> bool {
|
||||||
@@ -55,9 +58,11 @@ pub fn run(element: &mut Element) -> bool {
|
|||||||
clear();
|
clear();
|
||||||
unsafe {
|
unsafe {
|
||||||
let c = c_run(element as *mut Element as *mut c_void);
|
let c = c_run(element as *mut Element as *mut c_void);
|
||||||
show_cursor();
|
if !c {
|
||||||
disable_raw_mode().unwrap();
|
show_cursor();
|
||||||
clear();
|
disable_raw_mode().unwrap();
|
||||||
|
clear();
|
||||||
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -94,8 +94,8 @@ pub trait ElementCore: Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Component: ElementCore + std::fmt::Debug {
|
pub trait Component: ElementCore + std::fmt::Debug {
|
||||||
fn render(&self, state: State) -> String {
|
fn render(&self, focused: bool) -> String {
|
||||||
_ = state;
|
_ = focused;
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -29,7 +29,7 @@ use osui_element::{elem_fn, element};
|
|||||||
pub struct Text {}
|
pub struct Text {}
|
||||||
|
|
||||||
impl Component for Text<'_> {
|
impl Component for Text<'_> {
|
||||||
fn render(&self, _: crate::State) -> String {
|
fn render(&self, _: bool) -> String {
|
||||||
if let Children::Text(text) = &self.children {
|
if let Children::Text(text) = &self.children {
|
||||||
text.clone()
|
text.clone()
|
||||||
} else {
|
} else {
|
||||||
@@ -66,21 +66,17 @@ pub struct Div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Component for 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());
|
let mut frame = crate::utils::create_frame(self.width.get_value(), self.height.get_value());
|
||||||
|
|
||||||
if let Children::Children(children, child) = &self.children {
|
if let Children::Children(children, child) = &self.children {
|
||||||
for (i, elem) in children.iter().enumerate() {
|
for (i, elem) in children.iter().enumerate() {
|
||||||
if i == *child {
|
crate::utils::render_to_frame(
|
||||||
crate::utils::render_to_frame(state, self.width.get_value(), &mut frame, elem);
|
focused && i == *child,
|
||||||
} else {
|
self.width.get_value(),
|
||||||
crate::utils::render_to_frame(
|
&mut frame,
|
||||||
crate::State::Normal,
|
elem,
|
||||||
self.width.get_value(),
|
);
|
||||||
&mut frame,
|
|
||||||
elem,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,14 +138,18 @@ impl Component for Div<'_> {
|
|||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Button {
|
pub struct Button {
|
||||||
pub on_click: Handler<Button<'a>>,
|
pub on_click: Handler<Button<'a>>,
|
||||||
|
pub state: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for Button<'_> {
|
impl Component for Button<'_> {
|
||||||
fn render(&self, state: State) -> String {
|
fn render(&self, focused: bool) -> String {
|
||||||
match state {
|
if self.state == "click" {
|
||||||
State::Custom(_) => self.style.write("click", &self.children.get_text()),
|
return 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()),
|
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
|
/// Render to a frame
|
||||||
pub fn render_to_frame(
|
pub fn render_to_frame(
|
||||||
state: crate::State,
|
focused: bool,
|
||||||
width: usize,
|
width: usize,
|
||||||
frame: &mut Vec<String>,
|
frame: &mut Vec<String>,
|
||||||
element: &Element,
|
element: &Element,
|
||||||
) {
|
) {
|
||||||
let data = element.get_data();
|
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() {
|
if (data.1 + i) < frame.len() {
|
||||||
let frame_line = frame.get_mut(data.1 + i).unwrap();
|
let frame_line = frame.get_mut(data.1 + i).unwrap();
|
||||||
match data.0 {
|
match data.0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user