2024-05-24 15:27:30 -04:00

211 lines
8.0 KiB
Rust

use imgui::*;
mod support;
fn main() {
let mut humans = vec![
HumanData {
name: "Joonas",
favorite_number: 102,
favorite_fruit_maybe: "Dutch",
},
HumanData {
name: "Thom",
favorite_number: 314,
favorite_fruit_maybe: "Rice",
},
HumanData {
name: "Jack",
favorite_number: 611,
favorite_fruit_maybe: "Mangoes",
},
];
let mut t2_flags = TableFlags::REORDERABLE
| TableFlags::HIDEABLE
| TableFlags::RESIZABLE
| TableFlags::NO_BORDERS_IN_BODY;
support::simple_init(file!(), move |_, ui| {
ui.window("Input text callbacks")
.size([800.0, 400.0], Condition::FirstUseEver)
.build(|| {
if let Some(_t) = ui.begin_table("Basic-Table", 3) {
// we must also call `next_row` here, because we declined
// to set up header rows. If we set up header rows ourselves,
// we will call `table_header_rows` instead, and if we use
// `begin_table_header`, then the initial call will be handled for us.
ui.table_next_row();
// note you MUST call `next_column` at least to START
// Let's walk through a table like it's an iterator...
ui.table_set_column_index(0);
ui.text("x: 0, y: 0");
ui.table_next_column();
ui.text("x: 1, y: 0");
ui.table_next_column();
ui.text("x: 2, y: 0");
// // calling next column again will wrap us around to 0-1,
// // since we've exhausted our 3 columns.
ui.table_next_column();
ui.text("x: 0, y: 1");
// // Let's do this manually now -- we can set each column ourselves...
ui.table_set_column_index(1);
ui.text("x: 1, y: 1");
ui.table_set_column_index(2);
ui.text("x: 2, y: 1");
// you CAN go back...
ui.table_set_column_index(1);
// however, you should call `new_line`, since otherwise
// we'd right on top of our `x: 1, y: 1` text.
ui.new_line();
ui.text("our of order txt");
}
ui.separator();
ui.text("Let's add some headers");
if let Some(_t) = ui.begin_table_header(
"table-headers",
[
TableColumnSetup::new("Name"),
TableColumnSetup::new("Age"),
TableColumnSetup::new("Favorite fruit"),
],
) {
// note that we DON'T have to call "table_next_row" here -- that's taken care
// of for us by `begin_table_header`, since it actually calls `table_headers_row`
// but we DO need to call column!
// but that's fine, we'll use a loop
for i in 0..3 {
let names = ["Joonas", "Thom", "Jack"];
let fruit = ["Dutch", "Rice", "Mangoes"];
ui.table_next_column();
ui.text(names[i]);
ui.table_next_column();
ui.text((i * 9).to_string());
ui.table_next_column();
ui.text(fruit[i]);
}
}
ui.separator();
ui.text("Let's do some context menus");
ui.text(
"context menus are created, by default, from the flags passed\
while making the table, or each row.\n\
Notice how toggling these checkboxes changes the context menu.",
);
ui.checkbox_flags("Reorderable", &mut t2_flags, TableFlags::REORDERABLE);
ui.same_line();
ui.checkbox_flags("Hideable", &mut t2_flags, TableFlags::HIDEABLE);
ui.same_line();
ui.checkbox_flags("Resizable", &mut t2_flags, TableFlags::RESIZABLE);
if let Some(_t) = ui.begin_table_header_with_flags(
"table-headers2",
[
TableColumnSetup::new("Name"),
TableColumnSetup::new("Age"),
TableColumnSetup::new("Favorite fruit"),
],
t2_flags,
) {
// note that we DON'T have to call "table_next_row" here -- that's taken care
// of for us by `begin_table_header`, since it actually calls `table_headers_row`
// but we DO need to call column!
// but that's fine, we'll use a loop
for i in 0..3 {
let names = ["Joonas", "Thom", "Jack"];
let fruit = ["Dutch", "Rice", "Mangoes"];
ui.table_next_column();
ui.text(names[i]);
ui.table_next_column();
ui.text((i * 9).to_string());
ui.table_next_column();
ui.text(fruit[i]);
}
}
ui.separator();
ui.text("Here's a table you can sort!");
ui.text("Check the code to see the two methods of doing it.");
if let Some(_t) = ui.begin_table_header_with_flags(
"table-headers3",
[
TableColumnSetup::new("Name"),
TableColumnSetup::new("Favorite Number"),
TableColumnSetup::new("Favorite fruit"),
],
TableFlags::SORTABLE,
) {
if let Some(sort_data) = ui.table_sort_specs_mut() {
sort_data
.conditional_sort(|specs| HumanData::sort_humans(&mut humans, specs));
// Can also sort this other way...
// if sort_data.should_sort() {
// HumanData::sort_humans(&mut humans, sort_data.specs());
// sort_data.set_sorted();
// }
}
for human in humans.iter() {
ui.table_next_column();
ui.text(human.name);
ui.table_next_column();
ui.text(human.favorite_number.to_string());
ui.table_next_column();
ui.text(human.favorite_fruit_maybe);
}
}
});
});
}
struct HumanData {
name: &'static str,
favorite_number: usize,
favorite_fruit_maybe: &'static str,
}
impl HumanData {
pub fn sort_humans(humans: &mut [Self], specs: Specs<'_>) {
let spec = specs.iter().next().unwrap();
if let Some(kind) = spec.sort_direction() {
match kind {
TableSortDirection::Ascending => match spec.column_idx() {
0 => humans.sort_by_key(|h| h.name),
1 => humans.sort_by_key(|h| h.favorite_number),
2 => humans.sort_by_key(|h| h.favorite_fruit_maybe),
_ => unimplemented!(),
},
TableSortDirection::Descending => match spec.column_idx() {
0 => humans.sort_by_key(|h| std::cmp::Reverse(h.name)),
1 => humans.sort_by_key(|h| std::cmp::Reverse(h.favorite_number)),
2 => humans.sort_by_key(|h| std::cmp::Reverse(h.favorite_fruit_maybe)),
_ => unimplemented!(),
},
}
}
}
}