#![cfg_attr(target_arch = "xtensa", no_std, no_main)]
#![cfg_attr(
target_arch = "xtensa",
feature(impl_trait_in_assoc_type, type_alias_impl_trait)
)]
use oxivgl::view::NavAction;
use oxivgl::{
enums::{EventCode, ObjState},
event::Event,
layout::FlexFlow,
style::lv_pct,
view::{register_event_on, View},
widgets::{Align, Checkbox, Label, Obj, Part, WidgetError},
};
#[derive(Default)]
struct Scroll7 {
cont: Option<Obj<'static>>,
high_label: Option<Label<'static>>,
low_label: Option<Label<'static>>,
checkbox: Option<Checkbox<'static>>,
top_num: i32,
bottom_num: i32,
running: bool,
}
impl Scroll7 {
fn load_item_back(&self, cont: &Obj<'static>, num: i32) {
if let Ok(item) = Obj::new(cont) {
item.size(lv_pct(100), 40);
if let Ok(lbl) = Label::new(&item) {
let mut s = heapless::String::<16>::new();
let _ = core::fmt::Write::write_fmt(&mut s, format_args!("{}", num));
lbl.text(&s);
}
}
}
fn load_item_front(&self, cont: &Obj<'static>, num: i32) {
if let Ok(item) = Obj::new(cont) {
item.size(lv_pct(100), 40);
if let Ok(lbl) = Label::new(&item) {
let mut s = heapless::String::<16>::new();
let _ = core::fmt::Write::write_fmt(&mut s, format_args!("{}", num));
lbl.text(&s);
}
item.move_to_index(0);
}
}
fn update_scroll(&mut self) {
if self.running {
return;
}
self.running = true;
let Some(ref cont) = self.cont else { self.running = false; return; };
while self.bottom_num > -30 && cont.get_scroll_bottom() < 200 {
self.bottom_num -= 1;
self.load_item_back(cont, self.bottom_num);
cont.update_layout();
}
while self.top_num < 30 && cont.get_scroll_top() < 200 {
self.top_num += 1;
let bot_before = cont.get_scroll_bottom();
self.load_item_front(cont, self.top_num);
cont.update_layout();
let bot_after = cont.get_scroll_bottom();
cont.scroll_by(0, bot_before - bot_after, false);
}
while cont.get_scroll_bottom() > 600 {
self.bottom_num += 1;
cont.delete_child(-1);
cont.update_layout();
}
while cont.get_scroll_top() > 600 {
self.top_num -= 1;
let bot_before = cont.get_scroll_bottom();
cont.delete_child(0);
cont.update_layout();
let bot_after = cont.get_scroll_bottom();
cont.scroll_by(0, bot_before - bot_after, false);
}
let mut s = heapless::String::<48>::new();
let _ = core::fmt::Write::write_fmt(
&mut s,
format_args!("current largest\nloaded value:\n{}", self.top_num),
);
if let Some(ref high_label) = self.high_label { high_label.text(&s); }
let mut s = heapless::String::<48>::new();
let _ = core::fmt::Write::write_fmt(
&mut s,
format_args!("current smallest\nloaded value:\n{}", self.bottom_num),
);
if let Some(ref low_label) = self.low_label { low_label.text(&s); }
self.running = false;
}
}
impl View for Scroll7 {
fn create(&mut self, container: &Obj<'static>) -> Result<(), WidgetError> {
let high_label = Label::new(container)?;
high_label.text("current largest\nloaded value:\n3");
high_label.align(Align::TopLeft, 10, 10);
let low_label = Label::new(container)?;
low_label.text("current smallest\nloaded value:\n3");
low_label.align(Align::BottomLeft, 10, -10);
let checkbox = Checkbox::new(container)?;
checkbox.text("show\nscrollbar");
checkbox.align(Align::LeftMid, 10, 0);
checkbox.bubble_events();
let cont = Obj::new(container)?;
cont.size(160, 220);
cont.align(Align::RightMid, -10, 0);
cont.set_flex_flow(FlexFlow::Column);
cont.style_opa(0, Part::Scrollbar);
let item = Obj::new(&cont)?;
item.size(lv_pct(100), 40);
let lbl = Label::new(&item)?;
lbl.text("3");
self.cont = Some(cont);
self.high_label = Some(high_label);
self.low_label = Some(low_label);
self.checkbox = Some(checkbox);
self.top_num = 3;
self.bottom_num = 3;
self.running = false;
if let Some(ref c) = self.cont { c.update_layout(); }
self.update_scroll();
Ok(())
}
fn register_events(&mut self) {
if let Some(ref cont) = self.cont { register_event_on(self, cont.handle()); }
if let Some(ref cb) = self.checkbox { register_event_on(self, cb.handle()); }
}
fn on_event(&mut self, event: &Event) -> NavAction {
if let Some(ref cont) = self.cont {
if event.code() == EventCode::SCROLL
&& event.current_target_handle() == cont.handle()
{
self.update_scroll();
return NavAction::None;
}
}
if let Some(ref checkbox) = self.checkbox {
if event.matches(checkbox, EventCode::VALUE_CHANGED) {
let checked = checkbox.has_state(ObjState::CHECKED);
let opa = if checked { 255u8 } else { 0u8 };
if let Some(ref cont) = self.cont {
cont.style_opa(opa, Part::Scrollbar);
}
}
}
NavAction::None
}
fn update(&mut self) -> Result<NavAction, WidgetError> {
Ok(NavAction::None)
}
}
oxivgl_examples_common::example_main!(Scroll7::default());