3 个版本 (破坏性更新)

0.3.0 2024 年 2 月 11 日
0.2.0 2024 年 2 月 8 日
0.1.0 2024 年 1 月 28 日

#461 in GUI

Apache-2.0

170KB
3.5K SLoC

Finestra

CI Crates.io Version GitHub License

Finestra 是一个简单实用的 Rust 桌面 UI 框架。它通过集成到各平台的本地 UI 后端,保持了每个平台的原生外观和感觉。使用 Finestra,您可以编写同时针对 Windows 和 macOS 的应用程序。

安装

Finestra 提供了一个 crate,其中包含您开始开发桌面应用程序所需的所有工具

[dependencies]
finestra = "0.1.0"

示例

以下示例通过提供一个按钮来演示 Finestra 的基本用法,每次点击按钮时,按钮的文本都会更新。

use finestra::*;

struct MyApplication;

impl AppDelegate<AppState> for Application {
    fn make_content_view(&mut self, state: &mut AppState, _: Window) -> impl finestra::View<Self, AppState>  {
        state.label.set("Count: 0");

        Button::new(&state.label)
            .with_on_click(|state: &mut AppState, window: Window| {
                state.count += 1;
                state.label.set(format!("Count: {}", state.count));

                if state.count % 10 == 0 {
                    window.create_dialog(format!("You clicked {} times!", state.count))
                        .show();
                }
            })
    }
}

#[derive(Debug, Default)]
struct AppState {
    count: usize,
    label: TextValue,
}

fn main() {
    App::with_state(MyApplication, AppState::default())
        .run();
}

用法

该 crate 提供了一个入口点,即 App 结构体。

App::new(MyApplication::default()).run()

为了响应常见事件(如 启动)以及 configurepopulate 窗口,您必须提供 AppDelegate 实现。

struct MyApplication;

impl AppDelegate for MyApplication {
    fn did_launch(&mut self, _: &mut ()) {
        println!("Taking Off 🚀");
    }

    fn configure_main_window(&mut self, _: &mut ()) -> WindowConfiguration {
        WindowConfiguration::new()
            .with_title("Exciting Window Title 🤩")
    }

    fn will_show_window(&mut self, _: Window, _: &mut ()) {
        println!("About to show the window, be prepared! 👀");
    }

    fn make_content_view(&mut self, _: &mut (), _: Window) -> impl View<Self> {
        Label::new("Welcome to Finestra!")
    }
}

状态

一个强大的应用程序开发工具是 State<T> 对象,它是一个共享和订阅对象,您可以使用它一次性编写,然后在任何地方更新。它类似于 WPF 的 绑定 和 SwiftUI 的 绑定。它还与库深度融合,例如,允许您在传递 State<String> 的任何地方传递 String/&str

在以下示例中,用户可以通过更改 TextField 的内容来修改窗口的标题。

struct Application;

impl AppDelegate<AppState> for Application {
    fn configure_main_window(&mut self, state: &mut AppState) -> WindowConfiguration {
        state.title.set("My Application");

        WindowConfiguration::new()
            .with_title(state.title.clone())
    }

    fn make_content_view(&mut self, state: &mut AppState, _: Window) -> impl finestra::View<Self, AppState>  {
        Stack::horizontal()
            .with(Label::new("Choose a title:"))
            .with(TextField::new(state.title.clone()))
    }
}

#[derive(Debug, Default)]
struct AppState {
    title: TextValue,
}

fn main() {
    App::with_state(Application, AppState::default())
        .run();
}

点击此处查看完整示例

堆叠

要将多个项目放置在同一行或列中,请使用 Stack 视图。这可以是水平(行状)或垂直(列状)。

fn make_content_view(&mut self, _: &mut (), _: Window) -> impl finestra::View<Self, ()> {
    Stack::horizontal()
        .with(Label::new("Hello, world!"))
        .with(Button::new("Click Me"))
        .with(Button::new("Goodbye, world!"))
}

要了解如何将这些功能结合起来创建强大的界面,请查看 计算器应用程序 示例。

对话框

当发生需要用户注意的特定事件时,您可以使用 对话框

use rand::seq::SliceRandom;

const FRUITS: &[&str] = &[
    "Apple", "Banana",
    "Strawberry", "Orange",
    "Kiwi", "Pear",
    "Berries", "Lemon",
    // "Tomato",
];

Button::new("Random Fruit")
    .with_on_click(|_, window| {
        window.create_dialog(FRUITS.choose(&mut rand::thread_rng()))
                .title("Fruit")
                .kind(DialogKind::Informational)
                .show();
    })

有关更多信息,请参阅 DialogBuilderDialogKind 的文档。

颜色

要使用与 Finestra 支持的每个平台都一致的色彩,可以使用 SystemColor 枚举

Label::new("BlueExampleSoftware")
    .with_color(Color::system(SystemColor::Blue))

这将确保您始终使用正确的颜色,并与系统应用程序保持一致。

如果您需要使用特定颜色,可以使用 Color::rgb()Color::rgba() 函数

Label::new("Maroon Balloon 🎈")
    .with_color(Color::rgb(155, 68, 68))

您可以使用 State<Color> 模式自然地动态更改颜色。请参阅 Disco Button 示例以了解其实现方式。

组件概述

以下组件目前由 Finestra 支持

  • Button 可以用来触发特定操作。
  • ImageView 可以显示图片。
  • Label 包含单行文本。
  • Stack 可以水平或垂直放置项目。
  • TextBlock 可以包含多行文本,并允许进行特定对齐。
  • TextField 可以用来请求用户输入特定字符串。

理由

操作系统通常指定它们自己的设计语言,例如 Apple 的 人机界面指南 和 Microsoft 的 Windows 11 设计原则。这些指南提供以使用户能够体验到一致且熟悉的用户界面,并且遵守这些指南通常会被您的应用程序用户所欣赏,就像 Arc for Windows 在 X/Twitter 上受到赞扬

_TODO: 更新博客文章_

进一步阅读

版权 (C) 2024 Tristan Gerritsen

根据 Apache 许可证 2.0 版(“许可证”);除非遵守许可证,否则不得使用此文件。您可以在 https://apache.ac.cn/licenses/LICENSE-2.0 获取许可证副本。

除非适用法律要求或书面同意,否则根据许可证分发的软件按“现状”基础分发,不提供任何类型的保证或条件,无论是明示的还是默示的。有关许可证的具体语言,请参阅许可证。

除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交给Serde的任何贡献,将按上述方式双授权,不附加任何其他条款或条件。

依赖项

~1-41MB
~616K SLoC