Crate fltkrs_richdisplay
source ·Expand description
富文本查看器,支持图文混排,支持历史内容回顾。支持fluid
设计器。
创建组件示例:
use fltk::{app, window};
use fltk::enums::{Event, Key};
use fltk::prelude::{GroupExt, WidgetBase, WidgetExt, WindowExt};
use log::error;
use fltkrs_richdisplay::rich_text::RichText;
use fltkrs_richdisplay::{RichDataOptions, UserData};
#[tokio::main]
async fn main() {
let app = app::App::default();
let mut win = window::Window::default().with_size(1000, 600).center_screen();
let mut rich_text = RichText::new(100, 120, 800, 400, None);
rich_text.set_cache_size(200);
win.end();
win.show();
let ud = UserData::new_text("dev@DESKTOP-PCL7MBI:\t~$ ls\r\n".to_string());
rich_text.append(ud);
app.run().unwrap();
}
另一个支持互动的复杂示例,鼠标右键点击可互动的数据段会产生互动消息:
use fltk::{app, window};
use fltk::enums::{Color, Event, Font, Key};
use fltk::prelude::{GroupExt, WidgetBase, WidgetExt, WindowExt};
use log::error;
use fltkrs_richdisplay::rich_text::RichText;
use fltkrs_richdisplay::{RichDataOptions, UserData, CallbackData, DocEditType};
pub enum GlobalMessage {
ContentData(UserData),
UpdateData(RichDataOptions),
DisableData(i64),
}
#[tokio::main]
async fn main() {
let app = app::App::default();
let mut win = window::Window::default().with_size(1000, 600).center_screen();
win.make_resizable(true);
let mut rich_text = RichText::new(100, 120, 800, 400, None);
// 互动消息通道
let (action_sender, mut action_receiver) = tokio::sync::mpsc::channel::<CallbackData>(100);
// 自定义回调函数,当用户鼠标右键点击可互动的数据段时,组件会调用回调函数。
let cb_fn = {
let sender_rc = action_sender.clone();
move |user_data| {
let sender = sender_rc.clone();
tokio::spawn(async move {
if let Err(e) = sender.send(user_data).await {
error!("发送用户操作失败: {:?}", e);
}
});
}
};
rich_text.set_notifier(cb_fn);
rich_text.set_cache_size(1000);
/*
启用PageUp/PageDown快捷键打开和关闭回顾区的功能支持。
使用鼠标滚轮进行打开/关闭回顾区的功能已经内置在模块包中,而PageUp/PageDown的快捷键无法被内置组件检测到,因此需要外层容器主动调用API实现。
包里提供的两个API接口为此提供支持:`RichText::auto_open_reviewer(&self)`和`RichText::auto_close_reviewer(&self)`。
*/
win.handle({
let rich_text_rc = rich_text.clone();
move |_, evt| {
let mut handled = false;
match evt {
Event::KeyDown => {
if app::event_key_down(Key::PageDown) {
handled = rich_text_rc.auto_close_reviewer();
} else if app::event_key_down(Key::PageUp) {
handled = rich_text_rc.auto_open_reviewer().unwrap();
}
}
_ => {}
}
handled
}
});
// App全局消息唯一通道
let (global_sender, global_receiver) = app::channel::<GlobalMessage>();
win.end();
win.show();
let global_sender_rc = global_sender.clone();
// 互动消息处理器
tokio::spawn(async move {
while let Some(cb_data) = action_receiver.recv().await {
if let CallbackData::Data(data) = cb_data {
if data.text.starts_with("10") {
let toggle = !data.blink;
let update_options = RichDataOptions::new(data.id).blink(toggle);
global_sender_rc.send(GlobalMessage::UpdateData(update_options));
}
}
}
});
let data = vec![
UserData::new_text("0dev@DESKTOP-PCL7MBI:\t~$ ls\r\n1分片\r\n2分片".to_string()),
UserData::new_text("3dev@DESKTOP-PCL7MBI:\t~$ ls\r\n".to_string()),
UserData::new_text("4dev@DESKTOP-PCL7MBI:\t~$ ls\r\nls -al".to_string()),
UserData::new_text("5dev@DESKTOP-PCL7MBI:\t~$ ls\r\n速度".to_string()).set_bg_color(Some(Color::Green)),
UserData::new_text("6dev@DESKTOP-PCL7MBII:\t~$ ls Downloads\r\n".to_string()).set_font_and_size(Font::Helvetica, 22),
UserData::new_text("7dev@DESKTOP-PCL7MBI:\t~$ ls\r\n".to_string()),
UserData::new_text("8dev@DESKTOP-PCL7MBI:~$ ls".to_string()).set_underline(true),
UserData::new_text("9dev@DESKTOP-PCL7MBI:~$ ls\r\n".to_string()).set_underline(true),
UserData::new_text("10 Right click me! 鼠标右键点击!\r\n".to_string()).set_font_and_size(Font::Helvetica, 20).set_clickable(true).set_blink(true),
UserData::new_text("11dev@DESKTOP-PCL7MBI:\t~$ ls\r\n".to_string()),
];
let mut docs: Vec<DocEditType> = Vec::new();
for ud in data {
docs.push(DocEditType::Data(ud));
}
rich_text.append_batch(&mut docs);
let mut has_recent_message = false;
while app.wait() {
if let Some(msg) = global_receiver.recv() {
match msg {
GlobalMessage::ContentData(data) => {
has_recent_message = true;
rich_text.append(data);
}
GlobalMessage::UpdateData(options) => {
rich_text.update_data(options);
}
GlobalMessage::DisableData(id) => {
rich_text.disable_data(id);
}
}
} else {
has_recent_message = false;
}
if !has_recent_message {
app::sleep(0.001);
app::awake();
}
}
}
Modules§
- 展示缓存数据的组件,数据可来自主视图(主视图+回顾区配合使用)的快照,也可直接填充外部数据,可滚动浏览。 当以历史模式(即脱离主视图单独使用)展示数据时,不应修改数据。
- 富文本查看器组件。
Structs§
- 互动行为定义。
- 请求新页数据的回调函数载体。 当视图滚动到页面底部或顶部时,通过鼠标滚轮或按键
PageDown
或PageUp
时,会触发执行预定义的回调函数, 若有更多可用的数据,用户应当在此时提供下一页或上一页数据。 - 回调函数载体。 当用户使用鼠标点击主视图或回顾区视图上的可互动数据段时,会执行该回调函数,并将点击目标处的数据作为参数传入回调函数。 用户可自由定义回调函数的具体行为。
- 用于表示鼠标点击图片时的事件信息。
- 数据片段调整属性。
- 用于表示窗口尺寸变化前后差异的数据结构。
- 用户提供的数据段结构。。
Enums§
- 回调函数的参数类型,用于区分来源事件。
- 数据段类型,当前支持文本和图片两种。
- 数据或操作类型。
- 分页请求参数
Constants§
- 用于衡量窗口尺寸的基本字符。若应用对窗口尺寸敏感,则建议使用等宽字体作为默认字体。
fltk
中Font::Screen
代表等宽字体。 - 闪烁强度切换间隔时间,目前使用固定频率。
- 默认字体尺寸。
- 默认的Tab宽度,使用空格代替。
- 高亮文本背景色,查询目标时所有匹配目标的背景色。
- 高亮文本焦点边框颜色,查询目标时当前正在聚焦的目标。
- 高亮文本焦点边框对比色,当查询目标时当前正在聚焦的目标在闪烁时切换的对比颜色。
- 高亮文本焦点边框弧度参数。
- 图片与其他内容之间的垂直间距。
- 图片与其他内容之间的水平间距。
- 从字体高度计算行高度使用的放大系数。
- 最亮的白色。
Functions§
- 获取指定颜色的对比色。若指定颜色为中等灰色(R/G/B值相等且在116-139之间),则返回白色。
- 获取指定颜色的亮色或暗色,若指定颜色的R/G/B值其中最大的超过128,则获取暗色,否则获取亮色。
- 依据RGB格式的图片计算其L8格式的灰度数据。
- 从影像中提取
RGB
数据,不会损失alpha通道数据。若传入None
则返回一个对应大小且色深为L8
的黑板。 - 加载图片文件并生成面板更新信息。