pub mod audio_scope;
pub mod badge;
pub mod block;
pub mod button;
pub mod chart;
pub mod checkbox;
pub mod code;
pub mod disclosure;
pub mod feed;
pub mod file_picker;
pub mod grid;
pub mod image;
pub mod input;
pub mod list;
pub mod logo;
pub mod markdown;
pub mod meter;
pub mod page_host;
pub mod progress;
pub mod radio;
pub mod richtext;
pub mod scroll;
pub mod separator;
pub mod spinner;
pub mod table;
pub mod tabs;
pub mod textarea;
pub mod viewport3d;
pub use crate::gfx::Bitmap;
pub use badge::{Badge, Tone};
pub use block::{Block, BorderKind, TitleAlign};
pub use button::{Button, ButtonStyle};
pub use chart::{BarChart, LineChart, Sparkline};
pub use checkbox::Checkbox;
pub use code::{code_token_color, CodeView};
pub use feed::{CustomBlock, Feed, FeedBlock, FeedItem, FeedState};
pub use grid::Grid;
pub use image::{Image, ImageAlign, ImageFit};
pub use input::TextInput;
pub use list::List;
pub use logo::Logo;
pub use markdown::MarkdownView;
pub use progress::Progress;
pub use radio::RadioGroup;
pub use richtext::RichTextView;
pub use scroll::Scroll;
pub use separator::Separator;
pub use spinner::{Spinner, SpinnerKind};
pub use table::{ColWidth, Column, Table};
pub use tabs::Tabs;
pub use textarea::{SubmitPolicy, TextArea, TextAreaState};
pub use viewport3d::Viewport3D;
pub use code::diff_token_color;
pub use code::data_token_color;
pub use feed::SyncSpec;
pub use chart::{TimeSeries, TimeSeriesState};
pub use audio_scope::AudioScope;
pub use meter::Meter;
pub use markdown::{MdSearchMatch, OutlineEntry};
pub use disclosure::Disclosure;
pub use page_host::PageHost;
pub use file_picker::{FileEntry, FilePicker, FileSource, StdFileSource};
pub use input::PasteAction;
pub(crate) type SharedCallback<Arg> = std::rc::Rc<std::cell::RefCell<Option<Box<dyn FnMut(Arg)>>>>;
pub(crate) fn theme_tokens(cx: crate::reactive::Scope) -> crate::theme::TokenSet {
match cx.use_context::<crate::reactive::Signal<&'static crate::theme::Theme>>() {
Some(sig) => sig.get().tokens,
None => crate::theme::default_theme().tokens,
}
}
#[cfg(test)]
pub(crate) mod itest_util;
#[cfg(test)]
pub(crate) mod test_util {
use crate::base::{Rect, Size};
use crate::ui::{BufferCanvas, Element};
pub fn draw_into(mut el: Element, size: Size) -> BufferCanvas {
let mut canvas = BufferCanvas::new(size);
let rect = Rect::from_size(size);
let mut draw = el.draw.take().expect("widget must have a draw closure");
draw(&mut canvas, rect);
canvas
}
pub fn row(canvas: &BufferCanvas, y: i32) -> String {
canvas.row_text(y)
}
}
#[cfg(test)]
mod lint_tests {
const SOURCES: [(&str, &str); 43] = [
("mod.rs", include_str!("mod.rs")),
("audio_scope.rs", include_str!("audio_scope.rs")),
("meter.rs", include_str!("meter.rs")),
("badge.rs", include_str!("badge.rs")),
("block.rs", include_str!("block.rs")),
("block_close.rs", include_str!("block_close.rs")),
("button.rs", include_str!("button.rs")),
("chart.rs", include_str!("chart.rs")),
("chart_time.rs", include_str!("chart_time.rs")),
("checkbox.rs", include_str!("checkbox.rs")),
("code.rs", include_str!("code.rs")),
("disclosure.rs", include_str!("disclosure.rs")),
("feed.rs", include_str!("feed.rs")),
("feed_draw.rs", include_str!("feed_draw.rs")),
("feed_item.rs", include_str!("feed_item.rs")),
("feed_sync.rs", include_str!("feed_sync.rs")),
("feed_typeset.rs", include_str!("feed_typeset.rs")),
("file_picker.rs", include_str!("file_picker.rs")),
(
"file_picker_source.rs",
include_str!("file_picker_source.rs"),
),
("file_picker_view.rs", include_str!("file_picker_view.rs")),
("grid.rs", include_str!("grid.rs")),
("image.rs", include_str!("image.rs")),
("input.rs", include_str!("input.rs")),
("paste_hook.rs", include_str!("paste_hook.rs")),
("list.rs", include_str!("list.rs")),
("logo.rs", include_str!("logo.rs")),
("markdown.rs", include_str!("markdown.rs")),
("markdown_doc.rs", include_str!("markdown_doc.rs")),
("markdown_image.rs", include_str!("markdown_image.rs")),
("markdown_search.rs", include_str!("markdown_search.rs")),
("page_host.rs", include_str!("page_host.rs")),
("page_host_bar.rs", include_str!("page_host_bar.rs")),
("progress.rs", include_str!("progress.rs")),
("radio.rs", include_str!("radio.rs")),
("richtext.rs", include_str!("richtext.rs")),
("scroll.rs", include_str!("scroll.rs")),
("separator.rs", include_str!("separator.rs")),
("spinner.rs", include_str!("spinner.rs")),
("table.rs", include_str!("table.rs")),
("tabs.rs", include_str!("tabs.rs")),
("textarea.rs", include_str!("textarea.rs")),
("textarea_model.rs", include_str!("textarea_model.rs")),
("viewport3d.rs", include_str!("viewport3d.rs")),
];
#[test]
fn no_color_literals_or_arithmetic_in_widgets() {
let hex = "from_".to_string() + "hex(";
let rgb = "Rgba::".to_string() + "rgb(";
let new = "Rgba::".to_string() + "new(";
let lerp = ".le".to_string() + "rp(";
let over = ".ov".to_string() + "er(";
let lum = ".lumin".to_string() + "ance(";
for (name, src) in SOURCES {
for needle in [&hex, &rgb, &new, &lerp, &over, &lum] {
assert!(
!src.contains(needle.as_str()),
"widget source {name} contains forbidden color spelling {needle:?} \
โ widgets consume tokens only (RT1-9b)"
);
}
}
}
#[test]
fn every_widget_module_is_linted() {
let this = include_str!("mod.rs");
for line in this.lines() {
let Some(name) = line
.trim()
.strip_prefix("pub mod ")
.and_then(|rest| rest.strip_suffix(';'))
else {
continue;
};
let file = format!("{name}.rs");
assert!(
SOURCES.iter().any(|(listed, _)| *listed == file),
"widget module {file} was added without joining the lint list"
);
}
}
}