use teksilo_canvas::{Rect, SizeProposal};
use teksilo_core::accessibility::AccessNodeBuilder;
use teksilo_core::widget::{LayoutContext, Widget, WidgetPlacement};
use teksilo_core::widget_id::WidgetId;
use teksilo_data::SortDirection;
#[derive(Debug)]
pub(crate) struct CellA11y {
child: WidgetId,
row_index_1based: usize,
col_index_1based: usize,
selected: bool,
is_row_header: bool,
name: Option<String>,
}
impl CellA11y {
pub(crate) fn new(
child: WidgetId,
row_index_1based: usize,
col_index_1based: usize,
selected: bool,
) -> Self {
Self {
child,
row_index_1based,
col_index_1based,
selected,
is_row_header: false,
name: None,
}
}
#[allow(dead_code)]
pub(crate) fn with_role_row_header(mut self, is_row_header: bool) -> Self {
self.is_row_header = is_row_header;
self
}
#[allow(dead_code)]
pub(crate) fn with_name(mut self, name: Option<String>) -> Self {
self.name = name;
self
}
}
impl Widget for CellA11y {
fn layout_response(
&self,
proposal: SizeProposal,
ctx: &LayoutContext,
) -> teksilo_core::widget::LayoutResponse {
ctx.child_size(self.child, proposal)
.unwrap_or_else(|| proposal.resolve(0.0, 0.0))
.into()
}
fn place_children(
&self,
bounds: Rect,
_proposal: SizeProposal,
children: &mut [WidgetPlacement],
_ctx: &LayoutContext,
) {
for child in children.iter_mut() {
child.origin = bounds.origin();
child.size = bounds.size();
}
}
fn accessibility(&self, builder: &mut AccessNodeBuilder) {
builder.set_role(if self.is_row_header {
teksilo_core::accesskit::Role::RowHeader
} else {
teksilo_core::accesskit::Role::Cell
});
if let Some(ref name) = self.name {
builder.set_name(name.clone());
}
builder.set_selected(self.selected);
builder.set_row_index(self.row_index_1based);
builder.set_column_index(self.col_index_1based);
}
fn children(&self) -> Vec<WidgetId> {
vec![self.child]
}
}
#[derive(Debug)]
pub(crate) struct TreeRowA11y {
child: WidgetId,
row_index_1based: usize,
level_1based: usize,
expanded: Option<bool>,
selected: bool,
position_in_set: usize,
size_of_set: usize,
}
impl TreeRowA11y {
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
child: WidgetId,
row_index_1based: usize,
level_1based: usize,
expanded: Option<bool>,
selected: bool,
position_in_set: usize,
size_of_set: usize,
) -> Self {
Self {
child,
row_index_1based,
level_1based,
expanded,
selected,
position_in_set,
size_of_set,
}
}
}
impl Widget for TreeRowA11y {
fn layout_response(
&self,
proposal: SizeProposal,
ctx: &LayoutContext,
) -> teksilo_core::widget::LayoutResponse {
ctx.child_size(self.child, proposal)
.unwrap_or_else(|| proposal.resolve(0.0, 0.0))
.into()
}
fn place_children(
&self,
bounds: Rect,
_proposal: SizeProposal,
children: &mut [WidgetPlacement],
_ctx: &LayoutContext,
) {
for child in children.iter_mut() {
child.origin = bounds.origin();
child.size = bounds.size();
}
}
fn accessibility(&self, builder: &mut AccessNodeBuilder) {
builder.set_role(teksilo_core::accesskit::Role::Row);
builder.set_selected(self.selected);
if let Some(exp) = self.expanded {
builder.set_expanded(exp);
}
builder.set_row_index(self.row_index_1based);
builder.inner_mut().set_level(self.level_1based.max(1));
builder
.inner_mut()
.set_position_in_set(self.position_in_set);
builder.inner_mut().set_size_of_set(self.size_of_set);
}
fn children(&self) -> Vec<WidgetId> {
vec![self.child]
}
}
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) struct ColumnHeaderA11y {
child: WidgetId,
col_index_1based: usize,
name: String,
sort: Option<SortDirection>,
}
#[allow(dead_code)] impl ColumnHeaderA11y {
pub(crate) fn new(
child: WidgetId,
col_index_1based: usize,
name: impl Into<String>,
sort: Option<SortDirection>,
) -> Self {
Self {
child,
col_index_1based,
name: name.into(),
sort,
}
}
}
impl Widget for ColumnHeaderA11y {
fn layout_response(
&self,
proposal: SizeProposal,
ctx: &LayoutContext,
) -> teksilo_core::widget::LayoutResponse {
ctx.child_size(self.child, proposal)
.unwrap_or_else(|| proposal.resolve(0.0, 0.0))
.into()
}
fn place_children(
&self,
bounds: Rect,
_proposal: SizeProposal,
children: &mut [WidgetPlacement],
_ctx: &LayoutContext,
) {
for child in children.iter_mut() {
child.origin = bounds.origin();
child.size = bounds.size();
}
}
fn accessibility(&self, builder: &mut AccessNodeBuilder) {
builder.set_role(teksilo_core::accesskit::Role::ColumnHeader);
builder.set_name(self.name.clone());
builder.set_column_index(self.col_index_1based);
if let Some(dir) = self.sort {
let ak_dir = match dir {
SortDirection::Ascending => teksilo_core::accesskit::SortDirection::Ascending,
SortDirection::Descending => teksilo_core::accesskit::SortDirection::Descending,
};
builder.inner_mut().set_sort_direction(ak_dir);
}
}
fn children(&self) -> Vec<WidgetId> {
vec![self.child]
}
}