abacus/abacus-ui/src/output_block.rs

131 lines
5.1 KiB
Rust

use abacus_core::Output;
use druid::{
widget::{Container, Flex, Label, Padding, Scroll, ViewSwitcher},
Color, FontDescriptor, FontFamily, FontWeight, Widget, WidgetExt,
};
use crate::data::Block;
const OUTPUT_FONT_SIZE: f64 = 16.0;
pub fn output_block() -> impl Widget<Block> {
ViewSwitcher::new(
|data: &Block, _env| data.clone(),
|selector: &Block, _data, _env| match &selector.output {
Output::Scalar(v) => {
let str = match v {
_ if v.is::<String>() => v.clone().cast::<String>(),
_ if v.is::<&str>() => v.clone().cast::<&str>().to_string(),
v => v.to_string(),
};
Box::new(Padding::new(
25.0,
Label::new(str)
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE)
.with_weight(FontWeight::BOLD),
)
.with_text_size(OUTPUT_FONT_SIZE)
.padding(10.0)
.background(Color::rgb8(30, 30, 30))
.rounded(4.0)
.expand_width(),
))
}
Output::Error(e) => Box::new(Padding::new(
25.0,
Label::new(e.to_string())
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE).with_weight(FontWeight::BOLD),
)
.with_text_alignment(druid::TextAlignment::Center)
.with_line_break_mode(druid::widget::LineBreaking::WordWrap)
.with_text_size(OUTPUT_FONT_SIZE)
.padding(10.0)
.background(Color::rgb8(30, 10, 10))
.expand_width(),
)),
Output::Series(series) => {
let mut flex = Flex::row();
for v in series.iter() {
flex.add_child(
Label::new(v.to_string())
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE)
.with_weight(FontWeight::BOLD),
)
.with_text_size(OUTPUT_FONT_SIZE)
.padding(3.0)
.border(Color::rgb8(60, 60, 60), 1.0),
);
}
Box::new(Padding::new(
25.0,
flex.padding(10.0)
.background(Color::rgb8(30, 30, 30))
.rounded(4.0)
.expand_width(),
))
}
Output::DataFrame(frame) => {
let mut flex = Flex::row();
for series in frame.iter() {
let mut col = Flex::column()
.cross_axis_alignment(druid::widget::CrossAxisAlignment::Fill);
col.add_child(
Label::new(series.name())
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE)
.with_weight(FontWeight::BLACK),
)
.with_text_size(OUTPUT_FONT_SIZE)
.with_text_color(Color::rgb8(150, 150, 150))
.padding(3.0)
.border(Color::rgb8(50, 50, 50), 1.0)
.background(Color::rgb8(40, 40, 40)),
);
for v in series.iter() {
col.add_child(
Label::new(format_dataframe_value(v))
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE)
.with_weight(FontWeight::MEDIUM),
)
.with_text_size(OUTPUT_FONT_SIZE)
.padding(3.0)
.border(Color::rgb8(50, 50, 50), 1.0),
);
}
flex.add_child(col);
}
Box::new(Padding::new(
25.0,
Container::new(
Scroll::new(flex.background(Color::rgb8(30, 30, 30)).expand_width())
.horizontal()
.expand_width(),
)
.rounded(4.0)
.border(Color::rgb8(30, 30, 30), 5.0)
.background(Color::rgb8(30, 30, 30))
.expand_width(),
))
}
Output::None => Box::new(Container::new(Label::new(""))),
},
)
}
fn format_dataframe_value(value: abacus_core::AnyValue) -> String {
match value {
abacus_core::AnyValue::Utf8(v) => v.to_string(),
abacus_core::AnyValue::Utf8Owned(v) => v,
_ => value.to_string(),
}
}