#widgets #events #graphics

fltk-evented

fltk-rs 的监听小部件

16 个不稳定版本 (4 个破坏性更新)

0.5.2 2024年3月18日
0.4.1 2023年6月17日
0.3.0 2023年3月31日
0.2.0 2022年4月5日
0.1.3 2021年11月2日

#467GUI

Download history 18/week @ 2024-03-27 28/week @ 2024-04-03 5/week @ 2024-04-10 1/week @ 2024-04-24 3/week @ 2024-05-01 2/week @ 2024-05-15 7/week @ 2024-05-22 2/week @ 2024-05-29 4/week @ 2024-06-05 1/week @ 2024-06-12

每月下载量:631

MIT 许可证

23KB
374

fltk-evented

该包提供了同步和异步的监听小部件,基本上可以包装任何 fltk-rs 小部件(实现 WidgetBaseWidgetExt),并提供 triggered() -> boolevent() -> Event 方法来处理事件循环中的事件,而不需要回调。它还提供了 on_<event> 方法,简化了事件处理,而您本需要直接使用小部件的 handle 方法。

用法

[dependencies]
fltk = "1.4"
fltk-evented = "0.5"

示例

use fltk::{
    prelude::*, 
    app,
    enums::{Color, Event},
    button::Button, frame::Frame, group::Flex, window::Window,
};
use fltk_evented::Listener;

fn main() {
    let a = app::App::default().with_scheme(app::Scheme::Gtk);
    app::set_font_size(20);

    let mut wind = Window::default()
        .with_size(160, 200)
        .center_screen()
        .with_label("Counter");
    let flex = Flex::default()
        .with_size(120, 160)
        .center_of_parent()
        .column();
    let mut but_inc: Listener<_> = Button::default().with_label("+").into();
    let mut frame = Frame::default();
    let mut but_dec: Listener<_> = Button::default().with_label("-").into();
    flex.end();
    wind.end();
    wind.show();

    let mut val = 0;
    frame.set_label(&val.to_string());

    while a.wait() {
        if but_inc.triggered() {
            val += 1;
            frame.set_label(&val.to_string());
        }

        if but_dec.triggered() {
            val -= 1;
            frame.set_label(&val.to_string());
        }

        fn button_color(btn: &mut Button, c: Color) {
            btn.set_color(c);
            btn.redraw();
        }

        match but_inc.event() {
            Event::Enter | Event::Move => button_color(&mut but_inc, Color::White),
            Event::Leave => button_color(&mut but_inc, Color::BackGround),
            _ => (),
        }

        match but_dec.event() {
            Event::Enter | Event::Move => button_color(&mut but_dec, Color::White),
            Event::Leave => button_color(&mut but_dec, Color::BackGround),
            _ => (),
        }
    }
}

使用 on_<event> 方法

use fltk::{
    app, button,
    enums::{Color, FrameType},
    prelude::*,
    window,
};
use fltk_evented::Listener;

fn main() {
    let app = app::App::default();
    let mut wind = window::Window::default().with_size(400, 300);
    wind.set_color(Color::White);
    let mut but: Listener<_> = button::Button::new(160, 210, 80, 35, "Click me!").into();
    but.set_frame(FrameType::FlatBox);
    but.set_color(Color::Cyan);
    but.set_selection_color(Color::Cyan.darker());
    but.clear_visible_focus();
    wind.end();
    wind.show();

    but.on_hover(|b| {
        b.set_color(Color::Cyan.lighter().lighter());
    });

    but.on_leave(|b| {
        b.set_color(Color::Cyan);
    });

    but.on_click(|b| {
        println!("Clicked");
        b.set_label_color(Color::White);
    });

    but.on_release(move |b| {
        wind.set_label("Button Released!");
        b.set_label_color(Color::Black);
    });

    app.run().unwrap();
}

异步示例

fltk-evented 可以与 tokio 或 async-std 一起使用,在事件循环中处理非阻塞异步调用。以下示例展示了使用 tokio 的用法。另一个使用 async-std 的示例可以在示例目录中找到。

use fltk::{prelude::*, *};
use fltk_evented::AsyncListener;

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let mut buf = text::TextBuffer::default();
    let a = app::App::default().with_scheme(app::Scheme::Gtk);
    app::set_font_size(20);

    let mut wind = window::Window::default()
        .with_size(400, 300)
        .center_screen()
        .with_label("Counter");
    let col = group::Pack::default()
        .with_size(400, 300)
        .center_of_parent()
        .with_type(group::PackType::Vertical);
    let mut editor = text::TextEditor::default().with_size(0, 240);
    editor.set_buffer(buf.clone());
    let getter: AsyncListener<_> = button::Button::default()
        .with_label("Get")
        .with_size(0, 60)
        .into();
    col.end();
    wind.end();
    wind.show();

    while a.wait() {
        if getter.triggered().await {
            let text = reqwest::get("https://rust-lang.net.cn")
                .await?
                .text()
                .await?;
            buf.set_text(&text);
        }
    }
    Ok(())
}

依赖项

~13–25MB
~415K SLoC