use crate::draw::command::DrawCommand;
use crate::draw::renderer::Renderer;
use crate::ecs::{Entity, World};
use crate::event::GestureHandler;
use crate::event::widget_input::tabbar_handler;
use crate::types::{Color, Fixed, Rect};
use crate::widget::view::{View, ViewCtx};
pub struct TabBar {
pub selected: u8,
pub count: u8,
pub indicator_offset: Fixed,
pub indicator_color: Color,
pub indicator_height: Fixed,
}
impl TabBar {
pub fn new(count: u8) -> Self {
Self {
selected: 0,
count,
indicator_offset: Fixed::ZERO,
indicator_color: Color::rgb(88, 166, 255),
indicator_height: Fixed::from_int(2),
}
}
pub fn with_indicator(mut self, color: Color, height: impl Into<Fixed>) -> Self {
self.indicator_color = color;
self.indicator_height = height.into();
self
}
}
fn tab_bar_render(
renderer: &mut dyn Renderer,
world: &World,
entity: Entity,
rect: &Rect,
ctx: &mut ViewCtx,
) {
let Some(tb) = world.get::<TabBar>(entity) else {
return;
};
if tb.count == 0 {
return;
}
let tab_w = rect.w / Fixed::from_int(tb.count as i32);
let indicator_x = rect.x + tb.indicator_offset * tab_w;
let indicator_y = rect.y + rect.h - tb.indicator_height;
renderer.draw(
&DrawCommand::Fill {
area: Rect {
x: indicator_x,
y: indicator_y,
w: tab_w,
h: tb.indicator_height,
},
transform: ctx.transform,
quad: ctx.quad,
color: tb.indicator_color,
radius: Fixed::ZERO,
opa: 255,
},
ctx.clip,
);
}
fn tab_bar_attach(world: &mut World, entity: Entity) {
if world.get::<TabBar>(entity).is_none() {
return;
}
if world.get::<GestureHandler>(entity).is_some() {
return;
}
world.insert(
entity,
GestureHandler {
on_gesture: tabbar_handler,
},
);
}
pub fn view() -> View {
View {
name: "TabBar",
priority: 60,
render: tab_bar_render,
auto_attach: Some(tab_bar_attach),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defaults() {
let tb = TabBar::new(4);
assert_eq!(tb.count, 4);
assert_eq!(tb.selected, 0);
assert_eq!(tb.indicator_offset, Fixed::ZERO);
}
#[test]
fn with_indicator_overrides() {
let tb = TabBar::new(3).with_indicator(Color::rgb(255, 0, 0), 5);
assert_eq!(tb.indicator_color.r, 255);
assert_eq!(tb.indicator_height, Fixed::from_int(5));
}
}