use core::{cell::Cell, ops::Deref, ptr::null_mut};
use oxivgl_sys::*;
use super::{
LVGL_SCALE, WidgetError,
obj::{AsLvHandle, Obj},
to_lvgl,
};
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BarMode {
Normal = oxivgl_sys::lv_bar_mode_t_LV_BAR_MODE_NORMAL,
Symmetrical = oxivgl_sys::lv_bar_mode_t_LV_BAR_MODE_SYMMETRICAL,
Range = oxivgl_sys::lv_bar_mode_t_LV_BAR_MODE_RANGE,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BarOrientation {
Auto = lv_bar_orientation_t_LV_BAR_ORIENTATION_AUTO,
Horizontal = lv_bar_orientation_t_LV_BAR_ORIENTATION_HORIZONTAL,
Vertical = lv_bar_orientation_t_LV_BAR_ORIENTATION_VERTICAL,
}
#[derive(Debug)]
pub struct Bar<'p> {
obj: Obj<'p>,
max: Cell<f32>,
}
impl<'p> AsLvHandle for Bar<'p> {
fn lv_handle(&self) -> *mut lv_obj_t {
self.obj.lv_handle()
}
}
impl<'p> Deref for Bar<'p> {
type Target = Obj<'p>;
fn deref(&self) -> &Obj<'p> {
&self.obj
}
}
impl<'p> Bar<'p> {
pub fn new(parent: &impl AsLvHandle) -> Result<Self, WidgetError> {
let parent_ptr = parent.lv_handle();
assert_ne!(parent_ptr, null_mut(), "Parent widget cannot be null");
let handle = unsafe { lv_bar_create(parent_ptr) };
if handle.is_null() {
Err(WidgetError::LvglNullPointer)
} else {
Ok(Bar { obj: Obj::from_raw(handle), max: Cell::new(0.0) })
}
}
pub fn set_range(&self, max: f32) -> &Self {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
self.max.set(max);
unsafe { lv_bar_set_range(self.obj.handle(), 0, LVGL_SCALE) };
self
}
pub fn set_value(&self, value: f32) -> &Self {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_set_value(self.obj.handle(), to_lvgl(value, self.max.get()), false) };
self
}
pub fn set_range_raw(&self, min: i32, max: i32) -> &Self {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_set_range(self.obj.handle(), min, max) };
self
}
pub fn set_value_raw(&self, value: i32, anim: bool) -> &Self {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_set_value(self.obj.handle(), value, anim) };
self
}
pub fn get_value_raw(&self) -> i32 {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_get_value(self.obj.handle()) }
}
pub fn set_mode(&self, mode: BarMode) -> &Self {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_set_mode(self.obj.handle(), mode as lv_bar_mode_t) };
self
}
pub fn set_start_value_raw(&self, value: i32, anim: bool) -> &Self {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_set_start_value(self.obj.handle(), value, anim) };
self
}
pub fn get_start_value_raw(&self) -> i32 {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_get_start_value(self.obj.handle()) }
}
pub fn get_min_value(&self) -> i32 {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_get_min_value(self.obj.handle()) }
}
pub fn get_max_value(&self) -> i32 {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { lv_bar_get_max_value(self.obj.handle()) }
}
pub fn get_mode(&self) -> BarMode {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
unsafe { core::mem::transmute(lv_bar_get_mode(self.obj.handle())) }
}
pub fn set_orientation(&self, orientation: BarOrientation) -> &Self {
unsafe { lv_bar_set_orientation(self.lv_handle(), orientation as lv_bar_orientation_t) };
self
}
pub fn get_orientation(&self) -> BarOrientation {
let raw = unsafe { lv_bar_get_orientation(self.lv_handle()) };
match raw {
x if x == lv_bar_orientation_t_LV_BAR_ORIENTATION_HORIZONTAL => BarOrientation::Horizontal,
x if x == lv_bar_orientation_t_LV_BAR_ORIENTATION_VERTICAL => BarOrientation::Vertical,
_ => BarOrientation::Auto,
}
}
pub fn get_value(&self) -> f32 {
assert_ne!(self.obj.handle(), null_mut(), "Bar handle cannot be null");
let max = self.max.get();
if max == 0.0 {
return 0.0;
}
let raw = unsafe { lv_bar_get_value(self.obj.handle()) };
(raw as f32 / LVGL_SCALE as f32) * max
}
}