10 个版本 (破坏性更新)
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.0 | 2019年9月8日 |
在 #inspecting 中排名 16
每月下载量 42
用于 imgui-inspect
23KB
567 行代码(不包括注释)
imgui_inspect
这是一个使用 ImGui
和 Rust
实现的属性编辑器的简化实现。
更具体地说,这个包旨在成为 imgui 检查的 serde
。它定义了一个将值放入 imgui 并将其取出的通用接口。
为某些类型提供了默认实现,以便将其绘制为特定的小部件,但主要目标是使其易于实现您自己的首选渲染值的方式。
- 为每种小部件类型都有一个特质(例如
InspectRenderSlider
) - 为每种值类型都有一个实现(例如
f32
)
示例
如果您想看看这个包的实际应用,请查看 imgui-inspect-demo。在该目录下运行 cargo run
将启动它。
您还可以参考 minimum 中的代码。此视频 中的属性编辑器 展示了在此库中的使用。
许多更复杂的使用案例,例如自定义类型和处理多个选定的值,都已在其中实现。
状态
此包的整体设计不太可能更改,但实现了很多 imgui 小部件类型和值类型。
大部分未来的工作将包括
- 为每个 imgui 小部件类型添加特质
- 定义表示该 imgui 小部件有效选项的结构体
- 为 std 类型实现合理的默认值
这是一个相当直接的过程,并且存在基本示例,但这需要时间来添加它们。
随着需要支持更多类型,我会继续扩展这个功能。如果你需要缺少的功能,请提交PR!下面有详细的说明。
用法
为了实现默认渲染行为,请派生你的结构体上的Inspect
#[derive(Inspect)]
pub struct MyStruct {
pub first_value: f32,
pub second_value: f32,
}
要绘制,请使用UI窗口和你的结构体实例的引用调用它
// ....
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]传递的原因是通常需要选择多个对象。在这种情况下,渲染代码可以比较所有选定项目的值是否一致,或者在可变渲染的情况下,将更改应用到所有选定值。
简单定制
通过标记结构体成员,你可以获得略微不同的行为。这可以选择要绘制的小部件并调整它们的设置。
#[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,
}
高级定制
内部,派生Inspect实现了MyStruct上的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_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,
}
这将调用<f32 as 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 InspectRender[<[TYPE]> for [TYPE]
- 示例:
impl InspectRenderSlider<f32> for f32
- 示例:
添加新的小部件类型
总之,我们需要为小部件添加一个特性,为某些类型实现该特性,并将小部件/config选项添加到进程宏中
- 添加特性
- 将
InspectArgs[WIDGET]
和InspectRender[WIDGET]
添加到imgui-inspect/src/[WIDGET]/mod.rs
- 示例:在
imgui-inspect/src/slider
中的InspectArgsSlider
和InspectRenderSlider
InspectArgs[WIDGET]
中的值是可以输入到imgui中的选项InspectArgs[WIDGET]
的实现应将这些值传入imgui小部件
- 将
- 按照上述“添加默认值类型的小部件实现”说明为类型实现特性
- 将小部件添加到进程宏
- 将
InspectFieldArgs[WIDGET]
和InspectArgs[WIDGET]
添加到imgui-inspect-derive/src/inspect_macro/args/[WIDGET]_args.rs
- 示例:在
slider_args.rs
中的InspectFieldArgsSlider
和InspectFieldArgsSlider
InspectArgs[WIDGET]
是inspect-imgui中的相同结构的复制粘贴(因为它被重复,因为进程宏crate不能导出类型)InspectArgs[WIDGET]
是特定于小部件的唯一值,而InspectFieldArgs[WIDGET]
是通过宏可以更改的每个属性
- 示例:在
- 这些结构
InspectArgsDefault
和InspectFieldArgsDefault
应该是任何小部件可能的所有arg的超集。更新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
中将小部件类型添加到进程宏_derive
- 将
使imgui成为可选的
通常,你不想将imgui打包到最终产品中。但是,条件性地包含进程宏很尴尬。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
,可在其自己的许可证下使用。
依赖项
~2MB
~43K SLoC