mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-13 22:48:34 +00:00
updates tree node widgets
This commit is contained in:
parent
19e2c4672b
commit
2eebba5662
@ -383,24 +383,24 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
ui.checkbox("No collapse", &mut state.no_collapse);
|
||||
ui.checkbox("No close", &mut state.no_close);
|
||||
|
||||
TreeNode::new("Style").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Style") {
|
||||
ui.show_default_style_editor();
|
||||
});
|
||||
}
|
||||
}
|
||||
if CollapsingHeader::new("Widgets").build(ui) {
|
||||
TreeNode::new("Tree").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Tree") {
|
||||
for i in 0..5 {
|
||||
TreeNode::new(format!("Child {}", i)).build(ui, || {
|
||||
if let Some(_t) = ui.tree_node(format!("Child {}", i)) {
|
||||
ui.text("blah blah");
|
||||
ui.same_line();
|
||||
if ui.small_button("print") {
|
||||
println!("Child {} pressed", i);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
TreeNode::new("Bullets").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Bullets") {
|
||||
ui.bullet_text("Bullet point 1");
|
||||
ui.bullet_text("Bullet point 2\nOn multiple lines");
|
||||
ui.bullet();
|
||||
@ -408,22 +408,23 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
|
||||
ui.bullet();
|
||||
ui.small_button("Button");
|
||||
});
|
||||
TreeNode::new("Colored text").build(ui, || {
|
||||
}
|
||||
|
||||
if let Some(_t) = ui.tree_node("Colored text") {
|
||||
ui.text_colored([1.0, 0.0, 1.0, 1.0], "Pink");
|
||||
ui.text_colored([1.0, 1.0, 0.0, 1.0], "Yellow");
|
||||
ui.text_disabled("Disabled");
|
||||
});
|
||||
}
|
||||
|
||||
TreeNode::new("Multi-line text").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Multi-line text") {
|
||||
ui.input_text_multiline(
|
||||
"multiline",
|
||||
&mut state.text_multiline,
|
||||
[300., 100.],
|
||||
).build();
|
||||
});
|
||||
}
|
||||
|
||||
TreeNode::new("Word wrapping").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Word wrapping") {
|
||||
ui.text_wrapped(
|
||||
"This text should automatically wrap on the edge of \
|
||||
the window.The current implementation for text \
|
||||
@ -441,8 +442,9 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
|
||||
ui.text("Test paragraph 2:");
|
||||
// TODO
|
||||
});
|
||||
TreeNode::new("UTF-8 Text").build(ui, || {
|
||||
}
|
||||
|
||||
if let Some(_t) = ui.tree_node("UTF-8 Text") {
|
||||
ui.text_wrapped(
|
||||
"CJK text will only appear if the font was loaded \
|
||||
with theappropriate CJK character ranges. Call \
|
||||
@ -454,7 +456,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
ui.text("Kanjis: 日本語 (nihongo)");
|
||||
ui.input_text("UTF-8 input", &mut state.buf)
|
||||
.build();
|
||||
});
|
||||
}
|
||||
|
||||
ui.radio_button("radio a", &mut state.radio_button, 0);
|
||||
ui.same_line();
|
||||
@ -539,7 +541,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
ui.input_scalar_n("input scalar int array", &mut state.vec3i).build();
|
||||
ui.input_scalar_n("input scalar float array", &mut state.vec3f).build();
|
||||
|
||||
TreeNode::new("Multi-component Widgets").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Multi-component Widgets") {
|
||||
ui.input_float2("input float2", &mut state.vec2f)
|
||||
.build();
|
||||
ui.input_int2("input int2", &mut state.vec2i)
|
||||
@ -551,9 +553,9 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
ui.input_int3("input int3", &mut state.vec3i)
|
||||
.build();
|
||||
ui.spacing();
|
||||
});
|
||||
};
|
||||
|
||||
TreeNode::new("Color/Picker Widgets").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Color/Picker Widgets") {
|
||||
let s = &mut state.color_edit;
|
||||
ui.checkbox("With HDR", &mut s.hdr);
|
||||
ui.same_line();
|
||||
@ -652,12 +654,12 @@ CTRL+click on individual component to input value.\n",
|
||||
b = b.reference_color(s.ref_color_v)
|
||||
}
|
||||
b.build(ui);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if CollapsingHeader::new("Layout").build(ui) {
|
||||
TreeNode::new("Tabs").build(ui, || {
|
||||
TreeNode::new("Basic").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Tabs") {
|
||||
if let Some(_t) = ui.tree_node("Basic") {
|
||||
TabBar::new("basictabbar").build(ui, || {
|
||||
TabItem::new("Avocado").build(ui, || {
|
||||
ui.text("This is the Avocado tab!");
|
||||
@ -672,9 +674,9 @@ CTRL+click on individual component to input value.\n",
|
||||
ui.text("blah blah blah blah blah");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
TreeNode::new("Advanced & Close button").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Advanced & Close button") {
|
||||
|
||||
ui.separator();
|
||||
let s = &mut state.tabs;
|
||||
@ -725,11 +727,12 @@ CTRL+click on individual component to input value.\n",
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if CollapsingHeader::new("Popups & Modal windows").build(ui) {
|
||||
TreeNode::new("Popups").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Popups") {
|
||||
ui.text_wrapped(
|
||||
"When a popup is active, it inhibits interacting \
|
||||
with windows that are behind the popup. Clicking \
|
||||
@ -759,9 +762,9 @@ CTRL+click on individual component to input value.\n",
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
TreeNode::new("Modals").build(ui, || {
|
||||
if let Some(_t) = ui.tree_node("Modals") {
|
||||
ui.text_wrapped(
|
||||
"Modal windows are like popups but the user cannot close \
|
||||
them by clicking outside the window."
|
||||
@ -814,7 +817,7 @@ CTRL+click on individual component to input value.\n",
|
||||
ui.close_current_popup();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -86,39 +86,79 @@ impl<T> From<*mut T> for TreeNodeId<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder for a tree node widget
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[must_use]
|
||||
pub struct TreeNode<T, L = &'static str> {
|
||||
id: TreeNodeId<T>,
|
||||
label: Option<L>,
|
||||
opened: bool,
|
||||
opened_cond: Condition,
|
||||
flags: TreeNodeFlags,
|
||||
}
|
||||
impl Ui {
|
||||
/// Constructs a new tree node with just a name, and pushes it.
|
||||
///
|
||||
/// Use [tree_node_config] to access a builder to put additional
|
||||
/// configurations on the tree node.
|
||||
///
|
||||
/// [tree_node_config]: Self::tree_node_config
|
||||
pub fn tree_node<I, T>(&self, id: I) -> Option<TreeNodeToken<'_>>
|
||||
where
|
||||
I: Into<TreeNodeId<T>>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
self.tree_node_config(id).push()
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> TreeNode<T, &'static str> {
|
||||
/// Constructs a new tree node builder
|
||||
pub fn new<I: Into<TreeNodeId<T>>>(id: I) -> TreeNode<T, &'static str> {
|
||||
/// Constructs a new tree node builder.
|
||||
///
|
||||
/// Use [tree_node] to build a simple node with just a name.
|
||||
///
|
||||
/// [tree_node]: Self::tree_node
|
||||
pub fn tree_node_config<I, T>(&self, id: I) -> TreeNode<'_, T>
|
||||
where
|
||||
I: Into<TreeNodeId<T>>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
TreeNode {
|
||||
id: id.into(),
|
||||
label: None,
|
||||
opened: false,
|
||||
opened_cond: Condition::Never,
|
||||
flags: TreeNodeFlags::empty(),
|
||||
ui: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>, L: AsRef<str>> TreeNode<T, L> {
|
||||
/// Builder for a tree node widget
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[must_use]
|
||||
pub struct TreeNode<'a, T, L = &'static str> {
|
||||
id: TreeNodeId<T>,
|
||||
label: Option<L>,
|
||||
opened: bool,
|
||||
opened_cond: Condition,
|
||||
flags: TreeNodeFlags,
|
||||
ui: &'a Ui,
|
||||
}
|
||||
|
||||
impl<'a, T: AsRef<str>> TreeNode<'a, T, &'static str> {
|
||||
/// Constructs a new tree node builder
|
||||
#[deprecated(since = "0.9.0", note = "use `ui.tree_node` or `ui.tree_node_config`")]
|
||||
pub fn new<I: Into<TreeNodeId<T>>>(id: I, ui: &'a Ui) -> TreeNode<'a, T, &'static str> {
|
||||
TreeNode {
|
||||
id: id.into(),
|
||||
label: None,
|
||||
opened: false,
|
||||
opened_cond: Condition::Never,
|
||||
flags: TreeNodeFlags::empty(),
|
||||
ui,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AsRef<str>, L: AsRef<str>> TreeNode<'a, T, L> {
|
||||
/// Sets the tree node label
|
||||
pub fn label<I: Into<TreeNodeId<L2>>, L2: AsRef<str>>(self, label: L2) -> TreeNode<T, L2> {
|
||||
pub fn label<I: Into<TreeNodeId<L2>>, L2: AsRef<str>>(self, label: L2) -> TreeNode<'a, T, L2> {
|
||||
TreeNode {
|
||||
label: Some(label),
|
||||
id: self.id,
|
||||
opened: self.opened,
|
||||
opened_cond: self.opened_cond,
|
||||
flags: self.flags,
|
||||
ui: self.ui,
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,7 +281,7 @@ impl<T: AsRef<str>, L: AsRef<str>> TreeNode<T, L> {
|
||||
/// rendered, the token can be popped by calling `.pop()`.
|
||||
///
|
||||
/// Returns `None` if the tree node is not open and no content should be rendered.
|
||||
pub fn push(self, ui: &Ui) -> Option<TreeNodeToken<'_>> {
|
||||
pub fn push(self) -> Option<TreeNodeToken<'a>> {
|
||||
let open = unsafe {
|
||||
if self.opened_cond != Condition::Never {
|
||||
sys::igSetNextItemOpen(self.opened, self.opened_cond as i32);
|
||||
@ -249,9 +289,9 @@ impl<T: AsRef<str>, L: AsRef<str>> TreeNode<T, L> {
|
||||
match self.id {
|
||||
TreeNodeId::Str(id) => {
|
||||
let (id, label) = match self.label {
|
||||
Some(label) => ui.scratch_txt_two(id, label),
|
||||
Some(label) => self.ui.scratch_txt_two(id, label),
|
||||
None => {
|
||||
let v = ui.scratch_txt(id);
|
||||
let v = self.ui.scratch_txt(id);
|
||||
(v, v)
|
||||
}
|
||||
};
|
||||
@ -263,15 +303,15 @@ impl<T: AsRef<str>, L: AsRef<str>> TreeNode<T, L> {
|
||||
self.flags.bits() as i32,
|
||||
fmt_ptr(),
|
||||
match self.label {
|
||||
Some(v) => ui.scratch_txt(v),
|
||||
None => ui.scratch_txt(""),
|
||||
Some(v) => self.ui.scratch_txt(v),
|
||||
None => self.ui.scratch_txt(""),
|
||||
},
|
||||
),
|
||||
}
|
||||
};
|
||||
if open {
|
||||
Some(TreeNodeToken::new(
|
||||
ui,
|
||||
self.ui,
|
||||
!self.flags.contains(TreeNodeFlags::NO_TREE_PUSH_ON_OPEN),
|
||||
))
|
||||
} else {
|
||||
@ -282,8 +322,8 @@ impl<T: AsRef<str>, L: AsRef<str>> TreeNode<T, L> {
|
||||
/// Returns the result of the closure, if it is called.
|
||||
///
|
||||
/// Note: the closure is not called if the tree node is not open.
|
||||
pub fn build<R, F: FnOnce() -> R>(self, ui: &Ui, f: F) -> Option<R> {
|
||||
self.push(ui).map(|_node| f())
|
||||
pub fn build<R, F: FnOnce() -> R>(self, f: F) -> Option<R> {
|
||||
self.push().map(|_node| f())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user