mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-17 08:28:44 +00:00
Add ListClipper wrapper
This commit is contained in:
parent
65bfc1469e
commit
936e63bdfa
@ -49,6 +49,7 @@ struct State {
|
||||
dont_ask_me_next_time: bool,
|
||||
stacked_modals_item: usize,
|
||||
stacked_modals_color: [f32; 4],
|
||||
app_log: Vec<String>,
|
||||
|
||||
tabs: TabState,
|
||||
}
|
||||
@ -108,6 +109,7 @@ impl Default for State {
|
||||
dont_ask_me_next_time: false,
|
||||
stacked_modals_item: 0,
|
||||
stacked_modals_color: [0.4, 0.7, 0.0, 0.5],
|
||||
app_log: Vec::new(),
|
||||
tabs: TabState::default(),
|
||||
}
|
||||
}
|
||||
@ -312,6 +314,10 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
);
|
||||
}
|
||||
|
||||
if state.show_app_log {
|
||||
show_app_log(ui, &mut state.app_log);
|
||||
}
|
||||
|
||||
let mut window = Window::new(im_str!("ImGui Demo"))
|
||||
.title_bar(!state.no_titlebar)
|
||||
.resizable(!state.no_resize)
|
||||
@ -1232,3 +1238,56 @@ fn show_example_app_custom_rendering(ui: &Ui, state: &mut CustomRenderingState,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn show_app_log(ui: &Ui, app_log: &mut Vec<String>) {
|
||||
Window::new(im_str!("Example: Log"))
|
||||
.size([500.0, 400.0], Condition::FirstUseEver)
|
||||
.build(ui, || {
|
||||
if ui.small_button(im_str!("[Debug] Add 5 entries")) {
|
||||
let categories = ["info", "warn", "error"];
|
||||
let words = [
|
||||
"Bumfuzzled",
|
||||
"Cattywampus",
|
||||
"Snickersnee",
|
||||
"Abibliophobia",
|
||||
"Absquatulate",
|
||||
"Nincompoop",
|
||||
"Pauciloquent",
|
||||
];
|
||||
for _ in 0..5 {
|
||||
let category = categories[app_log.len() % categories.len()];
|
||||
let word = words[app_log.len() % words.len()];
|
||||
let frame = ui.frame_count();
|
||||
let time = ui.time();
|
||||
let text = format!(
|
||||
"{:05} {} Hello, current time is {:.1}, here's a word: {}",
|
||||
frame, category, time, word
|
||||
);
|
||||
app_log.push(text);
|
||||
}
|
||||
}
|
||||
if ui.button(im_str!("Clear"), [0.0, 0.0]) {
|
||||
app_log.clear();
|
||||
}
|
||||
ui.same_line(0.0);
|
||||
if ui.button(im_str!("Copy"), [0.0, 0.0]) {
|
||||
ui.set_clipboard_text(&ImString::from(app_log.join("\n")));
|
||||
}
|
||||
ui.separator();
|
||||
ChildWindow::new("logwindow")
|
||||
.flags(WindowFlags::HORIZONTAL_SCROLLBAR)
|
||||
.build(ui, || {
|
||||
let mut clipper = ListClipper::new()
|
||||
.items_count(app_log.len() as i32)
|
||||
.begin(ui);
|
||||
while clipper.step() {
|
||||
for line in clipper.display_start()..clipper.display_end() {
|
||||
ui.text(&app_log[line as usize]);
|
||||
}
|
||||
}
|
||||
if ui.scroll_y() >= ui.scroll_max_y() {
|
||||
ui.set_scroll_here_y();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ pub use self::input_widget::{
|
||||
pub use self::io::*;
|
||||
pub use self::layout::*;
|
||||
pub use self::legacy::*;
|
||||
pub use self::list_clipper::ListClipper;
|
||||
pub use self::plothistogram::PlotHistogram;
|
||||
pub use self::plotlines::PlotLines;
|
||||
pub use self::popup_modal::PopupModal;
|
||||
@ -58,6 +59,7 @@ pub mod internal;
|
||||
mod io;
|
||||
mod layout;
|
||||
mod legacy;
|
||||
mod list_clipper;
|
||||
mod plothistogram;
|
||||
mod plotlines;
|
||||
mod popup_modal;
|
||||
|
||||
82
imgui/src/list_clipper.rs
Normal file
82
imgui/src/list_clipper.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::thread;
|
||||
|
||||
use crate::sys;
|
||||
use crate::Ui;
|
||||
|
||||
pub struct ListClipper {
|
||||
items_count: i32,
|
||||
items_height: f32,
|
||||
}
|
||||
|
||||
impl ListClipper {
|
||||
pub fn new() -> Self {
|
||||
ListClipper {
|
||||
items_count: -1,
|
||||
items_height: -1.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn items_count(mut self, items_count: i32) -> Self {
|
||||
self.items_count = items_count;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn items_height(mut self, items_height: f32) -> Self {
|
||||
self.items_height = items_height;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn begin<'ui>(self, ui: &Ui<'ui>) -> ListClipperToken<'ui> {
|
||||
let list_clipper = unsafe {
|
||||
let list_clipper = sys::ImGuiListClipper_ImGuiListClipper();
|
||||
sys::ImGuiListClipper_Begin(list_clipper, self.items_count, self.items_height);
|
||||
list_clipper
|
||||
};
|
||||
ListClipperToken::new(ui, list_clipper)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ListClipperToken<'ui> {
|
||||
list_clipper: *mut sys::ImGuiListClipper,
|
||||
_phantom: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
impl<'ui> ListClipperToken<'ui> {
|
||||
fn new(_: &Ui<'ui>, list_clipper: *mut sys::ImGuiListClipper) -> Self {
|
||||
Self {
|
||||
list_clipper,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step(&mut self) -> bool {
|
||||
unsafe { sys::ImGuiListClipper_Step(self.list_clipper) }
|
||||
}
|
||||
|
||||
pub fn end(&mut self) {
|
||||
unsafe {
|
||||
sys::ImGuiListClipper_End(self.list_clipper);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_start(&self) -> i32 {
|
||||
unsafe { (*self.list_clipper).DisplayStart }
|
||||
}
|
||||
|
||||
pub fn display_end(&self) -> i32 {
|
||||
unsafe { (*self.list_clipper).DisplayEnd }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ui> Drop for ListClipperToken<'ui> {
|
||||
fn drop(&mut self) {
|
||||
if !self.step() {
|
||||
unsafe {
|
||||
sys::ImGuiListClipper_destroy(self.list_clipper);
|
||||
};
|
||||
} else if !thread::panicking() {
|
||||
panic!("step() was not called until it returned false");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user