use crate::ffi::util::{cstr_to_string, slice_from, state_mut};
use crate::terminal::WidgetCommand;
use std::ffi::c_void;
use std::os::raw::c_char;
#[no_mangle]
pub extern "C" fn ratatui_block(
handle: *mut c_void,
area_id: u32,
title: *const c_char,
borders: u8,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
state.commands.push(WidgetCommand::Block {
area_id,
title: cstr_to_string(title),
borders,
style,
});
}
#[no_mangle]
pub extern "C" fn ratatui_paragraph(
handle: *mut c_void,
area_id: u32,
text: *const c_char,
alignment: u8,
wrap: u8,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
state.commands.push(WidgetCommand::Paragraph {
area_id,
text: cstr_to_string(text),
alignment,
wrap: wrap != 0,
style,
});
}
#[no_mangle]
pub extern "C" fn ratatui_list(
handle: *mut c_void,
area_id: u32,
items: *const c_char,
selected: i32,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
state.commands.push(WidgetCommand::List {
area_id,
items: cstr_to_string(items),
selected,
style,
});
}
#[no_mangle]
pub extern "C" fn ratatui_gauge(
handle: *mut c_void,
area_id: u32,
ratio: f32,
label: *const c_char,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
state.commands.push(WidgetCommand::Gauge {
area_id,
ratio: ratio as f64,
label: cstr_to_string(label),
style,
});
}
#[no_mangle]
pub extern "C" fn ratatui_tabs(
handle: *mut c_void,
area_id: u32,
titles: *const c_char,
selected: u32,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
state.commands.push(WidgetCommand::Tabs {
area_id,
titles: cstr_to_string(titles),
selected,
style,
});
}
#[no_mangle]
pub extern "C" fn ratatui_sparkline(
handle: *mut c_void,
area_id: u32,
data: *const u64,
len: u32,
) {
if data.is_null() { return; }
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
let data_vec = slice_from(data, len as usize).to_vec();
state.commands.push(WidgetCommand::Sparkline { area_id, data: data_vec, style });
}
#[no_mangle]
pub extern "C" fn ratatui_table(
handle: *mut c_void,
area_id: u32,
data: *const c_char,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
state.commands.push(WidgetCommand::Table {
area_id,
data: cstr_to_string(data),
style,
});
}
#[no_mangle]
pub extern "C" fn ratatui_barchart(
handle: *mut c_void,
area_id: u32,
data: *const c_char,
bar_width: u16,
bar_gap: u16,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
let data_str = cstr_to_string(data);
let bars: Vec<(String, u64)> = data_str
.lines()
.filter_map(|line| {
let mut parts = line.splitn(2, '\t');
let label = parts.next()?.to_string();
let value: u64 = parts.next()?.trim().parse().ok()?;
Some((label, value))
})
.collect();
state.commands.push(WidgetCommand::BarChart { area_id, bars, bar_width, bar_gap, style });
}
#[no_mangle]
pub extern "C" fn ratatui_line_gauge(
handle: *mut c_void,
area_id: u32,
ratio: f32,
label: *const c_char,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
state.commands.push(WidgetCommand::LineGauge {
area_id,
ratio: ratio as f64,
label: cstr_to_string(label),
style,
});
}
#[no_mangle]
pub extern "C" fn ratatui_scrollbar(
handle: *mut c_void,
area_id: u32,
content_length: u32,
position: u32,
viewport_length: u32,
orientation: u8,
) {
let Some(state) = state_mut(handle) else { return; };
state.commands.push(WidgetCommand::Scrollbar {
area_id,
content_length,
position,
viewport_length,
orientation,
});
}
#[no_mangle]
pub extern "C" fn ratatui_calendar(
handle: *mut c_void,
area_id: u32,
year: i32,
month: u8,
day: u8,
) {
let Some(state) = state_mut(handle) else { return; };
state.commands.push(WidgetCommand::Calendar { area_id, year, month, day });
}
#[no_mangle]
pub extern "C" fn ratatui_table_ex(
handle: *mut c_void,
area_id: u32,
data: *const c_char,
col_types: *const u8,
col_values: *const u16,
col_count: u32,
selected_row: i32,
) {
let Some(state) = state_mut(handle) else { return; };
let style = state.take_style();
let col_constraints: Vec<(u8, u16)> =
if col_types.is_null() || col_values.is_null() || col_count == 0 {
Vec::new()
} else {
let n = col_count as usize;
let types = slice_from(col_types, n);
let values = slice_from(col_values, n);
types.iter().zip(values.iter()).map(|(&t, &v)| (t, v)).collect()
};
state.commands.push(WidgetCommand::TableEx {
area_id,
data: cstr_to_string(data),
col_constraints,
selected_row,
style,
});
}