13 个版本 (7 个破坏性更新)
0.8.0 | 2021 年 2 月 6 日 |
---|---|
0.7.0 | 2020 年 11 月 17 日 |
0.5.0 | 2020 年 5 月 30 日 |
0.4.0 | 2020 年 3 月 7 日 |
0.3.3 | 2019 年 9 月 28 日 |
#223 在 GUI 中
每月 46 次下载
23KB
541 代码行
imgui_inspect
简而言之,这是一个使用 ImGui
和 Rust
实现的属性编辑器的实现。
更具体地说,这个 crate 旨在成为 imgui 检查的 serde
。它定义了一个公共接口,用于将值放入 imgui 并将其导出。
为某些类型提供了默认实现,以便作为特定小部件绘制,但主要目标是使其轻松实现自己的首选值渲染方式。
- 每个小部件类型都有一个特例(例如
InspectRenderSlider
) - 每个值类型都有一个实现(例如
f32
)
示例
如果您想看到这个 crate 的实际应用,请查看 imgui-inspect-demo。在该目录下运行 cargo run
将启动它。
您还可以参考 minimum 中的代码。该视频 此视频 展示了在这个库中的应用。
其中实现了许多更复杂的使用案例,例如自定义类型和处理多个选定的值。
状态
这个 crate 的整体设计不太可能改变,但实现了许多 imgui 小部件类型和值类型。
未来的大部分工作将是
- 为每个 imgui 小部件类型添加特例
- 定义表示该 imgui 小部件有效选项的结构体
- 为 std 类型实现合理的默认值
这是一个相当直接的过程,并且存在基本示例,但添加它们需要时间。
随着我对更多类型的支持需求,我将继续扩展它,但如果您需要缺少的东西,请提交 PR!下面有详细的说明。
使用
对于默认渲染行为,在您的结构上派生 Inspect
#[derive(Inspect)]
pub struct MyStruct {
pub first_value: f32,
pub second_value: f32,
}
要绘制,请使用UI窗口和您struct实例的引用调用它
// ....
ui.text(im_str!("This...is...imgui!"));
ui.separator();
let my_struct = MyStruct::default(); // example, maybe get it from somewhere else instead
<MyStruct as InspectRenderDefault<MyStruct>>::render(
&[&my_struct],
&"my_struct_test",
ui,
&InspectArgsDefault::default()
);
my_struct被传递为&[&my_struct]的原因是通常需要选择多个对象。在这种情况下,渲染代码可以比较所有选中项的值是否一致,或者在可变渲染的情况下,将更改应用于所有选中值。
简单自定义
通过标记化struct成员,您可以获得略微不同的行为。这可以选择要绘制的小部件并调整它们的设置。
#[derive(Inspect)]
pub struct MyStruct {
// Use a slider widget with the given min/max values
#[inspect_slider(min_value = 5.0, max_value = 53.0)]
pub sliding_value: f32,
}
高级自定义
内部,为MyStruct实现Inspect时,实现InspectRenderDefault。但如果您需要执行自定义操作,可以手动实现它。
impl InspectRenderDefault<MyStruct> for MyStruct {
fn render(data: &[&MyStruct], label: &'static str, ui: &imgui::Ui, args: &InspectArgsDefault) {
ui.text("custom rendering is easy!");
}
fn render_mut(data: &mut [&mut MyStruct], label: &'static str, ui: &imgui::Ui, args: &InspectArgsDefault) {
ui.text("custom rendering is easy!");
}
}
API允许混合和匹配正在渲染的Render特性和类型。可以通过重写render_trait使单个类型以多种方式渲染。
pub trait InspectRenderMyCustomWidgetType<T> {
fn render(data: &[&T], label: &'static str, ui: &imgui::Ui, args: &InspectArgsDefault);
fn render_mut(data: &mut [&mut T], label: &'static str, ui: &imgui::Ui, args: &InspectArgsDefault);
}
#[derive(Inspect)]
pub struct MyStruct {
#[inspect(render_trait = "InspectRenderMyCustomWidgetType")]
pub a_value: f32,
}
这将调用<f32as InspectRenderMyCustomWidgetType>::render(...)
。这对于以几种不同的方式渲染同一类型非常有用。
有时您想在其他crate中为类型实现自己的渲染,但有一个问题...特性能在特性和类型本身所在的同一crate中实现。
您可以自己包装类型(例如,struct MyVec2(glm::Vec2)
),或者使用虚拟类型并重写proxy_type。
struct ImGlmVec2;
impl InspectRenderDefault<glm::Vec2> for ImGlmVec2 {
fn render(data: &[&glm::Vec2], label: &'static str, ui: &imgui::Ui, args: &InspectArgsDefault) {
// ...
}
fn render_mut(data: &mut [&mut glm::Vec2], label: &'static str, ui: &imgui::Ui, args: &InspectArgsDefault) {
// ...
}
}
#[derive(Inspect, Clone)]
pub struct MyStruct {
#[inspect(proxy_type = "ImGlmVec2")]
pub position: glm::Vec2,
}
此类型永远不会实例化。它仅用于解决应调用哪个函数:<ImGlmVec2 as InspectRenderDefault>::render(...)
为值类型添加默认小部件实现
请记住,如果您不想进行更改或不喜欢默认实现,您始终可以使用代理类型!
这很容易做到,只需要更改imgui-inspect
- 许多示例位于imgui-inspect/src
- 添加一个新模块
[WIDGET]/[WIDGET]_[TYPE]
- 示例:
slider/slider_f32.rs
- 示例:
- 添加实现:
impl<TYPE> InspectRender[WIDGET] for TYPE
- 示例:
impl<f32> InspectRenderSlider for f32
- 示例:
添加新的小部件类型
总之,我们需要添加一个特性,为一些类型实现该特性和将小部件/配置选项添加到proc宏。
- 添加特性
- 将
InspectArgs[WIDGET]
和InspectRender[WIDGET]
添加到imgui-inspect/src/[WIDGET]/mod.rs
- 示例:在
imgui-inspect/src/slider
中,InspectArgsSlider
和InspectRenderSlider
InspectArgs[WIDGET]
中的值是可以传递给 imgui 的选项InspectArgs[WIDGET]
的实现应该将这些值传递给 imgui 小部件
- 将
- 按照上述“为值类型添加默认小部件实现”的说明,为类型实现特制
- 将小部件添加到 proc macro
- 将
InspectFieldArgs[WIDGET]
和InspectArgs[WIDGET]
添加到imgui-inspect-derive/src/inspect_macro/args/[WIDGET]_args.rs
- 示例:在
slider_args.rs
中,InspectFieldArgsSlider
和InspectFieldArgsSlider
InspectArgs[WIDGET]
是 inspect-imgui 中相同结构的复制粘贴。(它被复制,因为 proc_macro 包不能导出类型)InspectArgs[WIDGET]
是小部件的独特值,而InspectFieldArgs[WIDGET]
是可以通过宏更改的每个属性
- 示例:在
- 这些结构
InspectArgsDefault
和InspectFieldArgsDefault
应该是任何小部件所有可能参数的超集。更新imgui-inspect-derive/src/inspect_macro/args/default_args.rs
imgui-inspect/src/default/mod.rs
- 在
imgui-inspect-derive/src/inspect_macro/mod.rs
中更新handle_inspect_types()
- 在
imgui-inspect-derive/src/lib.rs
中添加小部件类型到 proc_macro_derive
- 将
使 imgui 可选
通常,你不想将 imgui 部署到最终产品中。然而,有条件地包含 proc_macro 是不方便的。Rust 会对它不知道的任何宏发出警告,因此有条件地从项目中删除 imgui-inspect-derive 依赖项需要嘈杂的标记。
为了解决这个问题,imgui-inspect-derive 宏使用了一个特性 "generate_code"。禁用默认特性将阻止生成代码。
步骤
- 将 imgui-inspect 设置为可选
- 示例:
imgui-inspect = { version = "...", optional = true }
- 示例:
- 关闭 imgui-inspect-derive 默认特性
- 示例:
imgui-inspect-derive = { version = "...", default-features = false }
- 示例:
imgui-inspect-derive 生成样板代码,但实际上并不依赖于 imgui。禁用默认功能意味着 generate_code 功能将关闭,导致宏被解析,但不会生成代码。
贡献
所有贡献都假定在 MIT/Apache-2 许可下双许可。
许可
在 MIT 许可证和 Apache 许可证(版本 2.0)的条款下分发。
请参阅 LICENSE-APACHE 和 LICENSE-MIT。
字体目录包含多个字体,分别受其自己的许可证保护
- Feather,MIT
- Material Design Icons,SIL OFL 1.1
- FontAwesome 4.7.0,可在 SIL OFL 1.1 下使用
mplus-1p-regular.ttf
,可在其自己的许可证下使用。
依赖关系
约 15MB
约 284K SLoC