Reformat with rustfmt 0.9.0

This commit is contained in:
Joonas Javanainen 2017-11-02 22:01:02 +02:00
parent 08a5429e4c
commit 907f9dbdeb
No known key found for this signature in database
GPG Key ID: D39CCA5CB19B9179
16 changed files with 1702 additions and 1299 deletions

View File

@ -117,12 +117,17 @@ fn main() {
fn show_user_guide<'a>(ui: &Ui<'a>) { fn show_user_guide<'a>(ui: &Ui<'a>) {
ui.bullet_text(im_str!("Double-click on title bar to collapse window.")); ui.bullet_text(im_str!("Double-click on title bar to collapse window."));
ui.bullet_text(im_str!("Click and drag on lower right corner to resize window.")); ui.bullet_text(im_str!(
"Click and drag on lower right corner to resize window."
));
ui.bullet_text(im_str!("Click and drag on any empty space to move window.")); ui.bullet_text(im_str!("Click and drag on any empty space to move window."));
ui.bullet_text(im_str!("Mouse Wheel to scroll.")); ui.bullet_text(im_str!("Mouse Wheel to scroll."));
ui.bullet_text(im_str!("TAB/SHIFT+TAB to cycle through keyboard editable fields.")); ui.bullet_text(im_str!(
"TAB/SHIFT+TAB to cycle through keyboard editable fields."
));
ui.bullet_text(im_str!("CTRL+Click on a slider or drag box to input text.")); ui.bullet_text(im_str!("CTRL+Click on a slider or drag box to input text."));
ui.bullet_text(im_str!("While editing text: ui.bullet_text(im_str!(
"While editing text:
- Hold SHIFT or use mouse to select text - Hold SHIFT or use mouse to select text
- \ - \
CTRL+Left/Right to word jump CTRL+Left/Right to word jump
@ -134,7 +139,8 @@ fn show_user_guide<'a>(ui: &Ui<'a>) {
to revert to revert
- You can apply arithmetic operators +,*,/ on numerical \ - You can apply arithmetic operators +,*,/ on numerical \
values. values.
Use +- to subtract.")); Use +- to subtract."
));
} }
fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) { fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
@ -145,9 +151,11 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
show_example_app_main_menu_bar(ui, state) show_example_app_main_menu_bar(ui, state)
} }
if state.show_app_auto_resize { if state.show_app_auto_resize {
show_example_app_auto_resize(ui, show_example_app_auto_resize(
&mut state.auto_resize_state, ui,
&mut state.show_app_auto_resize); &mut state.auto_resize_state,
&mut state.show_app_auto_resize,
);
} }
if state.show_app_fixed_overlay { if state.show_app_fixed_overlay {
show_example_app_fixed_overlay(ui, &mut state.show_app_fixed_overlay); show_example_app_fixed_overlay(ui, &mut state.show_app_fixed_overlay);
@ -163,8 +171,10 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
ui.text(im_str!("ImGui {}", imgui::get_version())); ui.text(im_str!("ImGui {}", imgui::get_version()));
ui.separator(); ui.separator();
ui.text(im_str!("By Omar Cornut and all github contributors.")); ui.text(im_str!("By Omar Cornut and all github contributors."));
ui.text(im_str!("ImGui is licensed under the MIT License, see LICENSE for more \ ui.text(im_str!(
information.")); "ImGui is licensed under the MIT License, see LICENSE for more \
information."
));
}) })
} }
@ -182,50 +192,51 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
.build(|| { .build(|| {
ui.text(im_str!("ImGui says hello.")); ui.text(im_str!("ImGui says hello."));
ui.menu_bar(|| { ui.menu_bar(|| {
ui.menu(im_str!("Menu")) ui.menu(im_str!("Menu")).build(|| {
.build(|| { show_example_menu_file(ui, &mut state.file_menu); }); show_example_menu_file(ui, &mut state.file_menu);
ui.menu(im_str!("Examples")) });
.build(|| { ui.menu(im_str!("Examples")).build(|| {
ui.menu_item(im_str!("Main menu bar")) ui.menu_item(im_str!("Main menu bar"))
.selected(&mut state.show_app_main_menu_bar) .selected(&mut state.show_app_main_menu_bar)
.build(); .build();
ui.menu_item(im_str!("Console")) ui.menu_item(im_str!("Console"))
.selected(&mut state.show_app_console) .selected(&mut state.show_app_console)
.build(); .build();
ui.menu_item(im_str!("Simple layout")) ui.menu_item(im_str!("Simple layout"))
.selected(&mut state.show_app_layout) .selected(&mut state.show_app_layout)
.build(); .build();
ui.menu_item(im_str!("Long text display")) ui.menu_item(im_str!("Long text display"))
.selected(&mut state.show_app_long_text) .selected(&mut state.show_app_long_text)
.build(); .build();
ui.menu_item(im_str!("Auto-resizing window")) ui.menu_item(im_str!("Auto-resizing window"))
.selected(&mut state.show_app_auto_resize) .selected(&mut state.show_app_auto_resize)
.build(); .build();
ui.menu_item(im_str!("Simple overlay")) ui.menu_item(im_str!("Simple overlay"))
.selected(&mut state.show_app_fixed_overlay) .selected(&mut state.show_app_fixed_overlay)
.build(); .build();
ui.menu_item(im_str!("Manipulating window title")) ui.menu_item(im_str!("Manipulating window title"))
.selected(&mut state.show_app_manipulating_window_title) .selected(&mut state.show_app_manipulating_window_title)
.build(); .build();
ui.menu_item(im_str!("Custom rendering")) ui.menu_item(im_str!("Custom rendering"))
.selected(&mut state.show_app_custom_rendering) .selected(&mut state.show_app_custom_rendering)
.build(); .build();
}); });
ui.menu(im_str!("Help")) ui.menu(im_str!("Help")).build(|| {
.build(|| { ui.menu_item(im_str!("Metrics"))
ui.menu_item(im_str!("Metrics")) .selected(&mut state.show_app_metrics)
.selected(&mut state.show_app_metrics) .build();
.build(); ui.menu_item(im_str!("About ImGui"))
ui.menu_item(im_str!("About ImGui")) .selected(&mut state.show_app_about)
.selected(&mut state.show_app_about) .build();
.build(); });
});
}); });
ui.spacing(); ui.spacing();
if ui.collapsing_header(im_str!("Help")).build() { if ui.collapsing_header(im_str!("Help")).build() {
ui.text_wrapped(im_str!("This window is being created by the show_test_window() \ ui.text_wrapped(im_str!(
"This window is being created by the show_test_window() \
function. Please refer to the code for programming \ function. Please refer to the code for programming \
reference.\n\nUser Guide:")); reference.\n\nUser Guide:"
));
show_user_guide(ui); show_user_guide(ui);
} }
@ -244,55 +255,53 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
ui.slider_float(im_str!("bg alpha"), &mut state.bg_alpha, 0.0, 1.0) ui.slider_float(im_str!("bg alpha"), &mut state.bg_alpha, 0.0, 1.0)
.build(); .build();
ui.tree_node(im_str!("Style")) ui.tree_node(im_str!("Style")).build(|| {
.build(|| { // TODO: Reimplement style editor
// TODO: Reimplement style editor ui.show_default_style_editor();
ui.show_default_style_editor(); });
});
ui.tree_node(im_str!("Fonts")) ui.tree_node(im_str!("Fonts"))
.label(im_str!("Fonts ({})", "TODO")) .label(im_str!("Fonts ({})", "TODO"))
.build(|| { .build(|| {
ui.text_wrapped(im_str!("Tip: Load fonts with \ ui.text_wrapped(im_str!(
io.Fonts->AddFontFromFileTTF().")); "Tip: Load fonts with \
ui.tree_node(im_str!("Atlas texture")) io.Fonts->AddFontFromFileTTF()."
.build(|| { ));
// TODO ui.tree_node(im_str!("Atlas texture")).build(|| {
}); // TODO
}); });
});
} }
if ui.collapsing_header(im_str!("Widgets")).build() { if ui.collapsing_header(im_str!("Widgets")).build() {
ui.tree_node(im_str!("Tree")) ui.tree_node(im_str!("Tree")).build(|| for i in 0..5 {
.build(|| for i in 0..5 { ui.tree_node(im_str!("Child {}", i)).build(|| {
ui.tree_node(im_str!("Child {}", i)) ui.text(im_str!("blah blah"));
.build(|| { ui.same_line(0.0);
ui.text(im_str!("blah blah")); if ui.small_button(im_str!("print")) {
ui.same_line(0.0); println!("Child {} pressed", i);
if ui.small_button(im_str!("print")) { }
println!("Child {} pressed", i);
}
});
});
ui.tree_node(im_str!("Bullets"))
.build(|| {
ui.bullet_text(im_str!("Bullet point 1"));
ui.bullet_text(im_str!("Bullet point 2\nOn multiple lines"));
ui.bullet();
ui.text(im_str!("Bullet point 3 (two calls)"));
ui.bullet();
ui.small_button(im_str!("Button"));
}); });
ui.tree_node(im_str!("Colored text")) });
.build(|| { ui.tree_node(im_str!("Bullets")).build(|| {
ui.text_colored((1.0, 0.0, 1.0, 1.0), im_str!("Pink")); ui.bullet_text(im_str!("Bullet point 1"));
ui.text_colored((1.0, 1.0, 0.0, 1.0), im_str!("Yellow")); ui.bullet_text(im_str!("Bullet point 2\nOn multiple lines"));
ui.text_disabled(im_str!("Disabled")); ui.bullet();
}); ui.text(im_str!("Bullet point 3 (two calls)"));
ui.bullet();
ui.small_button(im_str!("Button"));
});
ui.tree_node(im_str!("Colored text")).build(|| {
ui.text_colored((1.0, 0.0, 1.0, 1.0), im_str!("Pink"));
ui.text_colored((1.0, 1.0, 0.0, 1.0), im_str!("Yellow"));
ui.text_disabled(im_str!("Disabled"));
});
ui.tree_node(im_str!("Word Wrapping")).build(|| { ui.tree_node(im_str!("Word Wrapping")).build(|| {
ui.text_wrapped(im_str!("This text should automatically wrap on the edge of \ ui.text_wrapped(im_str!(
"This text should automatically wrap on the edge of \
the window.The current implementation for text \ the window.The current implementation for text \
wrapping follows simple rulessuitable for English \ wrapping follows simple rulessuitable for English \
and possibly other languages.")); and possibly other languages."
));
ui.spacing(); ui.spacing();
ui.slider_float(im_str!("Wrap width"), &mut state.wrap_width, -20.0, 600.0) ui.slider_float(im_str!("Wrap width"), &mut state.wrap_width, -20.0, 600.0)
@ -305,18 +314,19 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
ui.text(im_str!("Test paragraph 2:")); ui.text(im_str!("Test paragraph 2:"));
// TODO // TODO
}); });
ui.tree_node(im_str!("UTF-8 Text")) ui.tree_node(im_str!("UTF-8 Text")).build(|| {
.build(|| { ui.text_wrapped(im_str!(
ui.text_wrapped(im_str!("CJK text will only appear if the font was loaded \ "CJK text will only appear if the font was loaded \
with theappropriate CJK character ranges. Call \ with theappropriate CJK character ranges. Call \
io.Font->LoadFromFileTTF()manually to load extra \ io.Font->LoadFromFileTTF()manually to load extra \
character ranges.")); character ranges."
));
ui.text(im_str!("Hiragana: かきくけこ (kakikukeko)")); ui.text(im_str!("Hiragana: かきくけこ (kakikukeko)"));
ui.text(im_str!("Kanjis: 日本語 (nihongo)")); ui.text(im_str!("Kanjis: 日本語 (nihongo)"));
ui.input_text(im_str!("UTF-8 input"), &mut state.buf) ui.input_text(im_str!("UTF-8 input"), &mut state.buf)
.build(); .build();
}); });
ui.radio_button(im_str!("radio a"), &mut state.radio_button, 0); ui.radio_button(im_str!("radio a"), &mut state.radio_button, 0);
ui.same_line(0.0); ui.same_line(0.0);
@ -326,25 +336,31 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
ui.separator(); ui.separator();
ui.label_text(im_str!("label"), im_str!("Value")); ui.label_text(im_str!("label"), im_str!("Value"));
ui.combo(im_str!("combo"), ui.combo(
&mut state.item, im_str!("combo"),
&[im_str!("aaaa"), &mut state.item,
im_str!("bbbb"), &[
im_str!("cccc"), im_str!("aaaa"),
im_str!("dddd"), im_str!("bbbb"),
im_str!("eeee")], im_str!("cccc"),
-1); im_str!("dddd"),
let items = [im_str!("AAAA"), im_str!("eeee"),
im_str!("BBBB"), ],
im_str!("CCCC"), -1,
im_str!("DDDD"), );
im_str!("EEEE"), let items = [
im_str!("FFFF"), im_str!("AAAA"),
im_str!("GGGG"), im_str!("BBBB"),
im_str!("HHHH"), im_str!("CCCC"),
im_str!("IIII"), im_str!("DDDD"),
im_str!("JJJJ"), im_str!("EEEE"),
im_str!("KKKK")]; im_str!("FFFF"),
im_str!("GGGG"),
im_str!("HHHH"),
im_str!("IIII"),
im_str!("JJJJ"),
im_str!("KKKK"),
];
ui.combo(im_str!("combo scroll"), &mut state.item2, &items, -1); ui.combo(im_str!("combo scroll"), &mut state.item2, &items, -1);
ui.input_text(im_str!("input text"), &mut state.text) ui.input_text(im_str!("input text"), &mut state.text)
.build(); .build();
@ -356,127 +372,126 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
ui.input_float3(im_str!("input float3"), &mut state.vec3f) ui.input_float3(im_str!("input float3"), &mut state.vec3f)
.build(); .build();
ui.tree_node(im_str!("Multi-component Widgets")) ui.tree_node(im_str!("Multi-component Widgets")).build(|| {
.build(|| { ui.input_float2(im_str!("input float2"), &mut state.vec2f)
ui.input_float2(im_str!("input float2"), &mut state.vec2f) .build();
.build(); ui.input_int2(im_str!("input int2"), &mut state.vec2i)
ui.input_int2(im_str!("input int2"), &mut state.vec2i) .build();
.build(); ui.spacing();
ui.spacing();
ui.input_float3(im_str!("input float3"), &mut state.vec3f) ui.input_float3(im_str!("input float3"), &mut state.vec3f)
.build(); .build();
ui.input_int3(im_str!("input int3"), &mut state.vec3i) ui.input_int3(im_str!("input int3"), &mut state.vec3i)
.build(); .build();
ui.spacing(); ui.spacing();
}); });
} }
if ui.collapsing_header(im_str!("Popups & Modal windows")) if ui.collapsing_header(im_str!("Popups & Modal windows"))
.build() { .build()
ui.tree_node(im_str!("Popups")) {
.build(|| { ui.tree_node(im_str!("Popups")).build(|| {
ui.text_wrapped(im_str!("When a popup is active, it inhibits interacting \ ui.text_wrapped(im_str!(
"When a popup is active, it inhibits interacting \
with windows that are behind the popup. Clicking \ with windows that are behind the popup. Clicking \
outside the popup closes it.")); outside the popup closes it."
let names = [im_str!("Bream"), ));
im_str!("Haddock"), let names = [
im_str!("Mackerel"), im_str!("Bream"),
im_str!("Pollock"), im_str!("Haddock"),
im_str!("Tilefish")]; im_str!("Mackerel"),
if ui.small_button(im_str!("Select..")) { im_str!("Pollock"),
ui.open_popup(im_str!("select")); im_str!("Tilefish"),
} ];
ui.same_line(0.0); if ui.small_button(im_str!("Select..")) {
ui.text(match state.selected_fish { ui.open_popup(im_str!("select"));
Some(index) => names[index].clone(), }
None => im_str!("<None>"), ui.same_line(0.0);
}); ui.text(match state.selected_fish {
ui.popup(im_str!("select"), || { Some(index) => names[index].clone(),
ui.text(im_str!("Aquarium")); None => im_str!("<None>"),
ui.separator();
for (index, name) in names.iter().enumerate() {
if ui.selectable(name.clone(),
false,
ImGuiSelectableFlags::empty(),
ImVec2::new(0.0, 0.0)) {
state.selected_fish = Some(index);
}
}
});
}); });
ui.popup(im_str!("select"), || {
ui.text(im_str!("Aquarium"));
ui.separator();
for (index, name) in names.iter().enumerate() {
if ui.selectable(
name.clone(),
false,
ImGuiSelectableFlags::empty(),
ImVec2::new(0.0, 0.0),
)
{
state.selected_fish = Some(index);
}
}
});
});
} }
}) })
} }
fn show_example_app_main_menu_bar<'a>(ui: &Ui<'a>, state: &mut State) { fn show_example_app_main_menu_bar<'a>(ui: &Ui<'a>, state: &mut State) {
ui.main_menu_bar(|| { ui.main_menu_bar(|| {
ui.menu(im_str!("File")) ui.menu(im_str!("File")).build(|| {
.build(|| { show_example_menu_file(ui, &mut state.file_menu); }); show_example_menu_file(ui, &mut state.file_menu);
ui.menu(im_str!("Edit")) });
.build(|| { ui.menu(im_str!("Edit")).build(|| {
ui.menu_item(im_str!("Undo")) ui.menu_item(im_str!("Undo"))
.shortcut(im_str!("CTRL+Z")) .shortcut(im_str!("CTRL+Z"))
.build(); .build();
ui.menu_item(im_str!("Redo")) ui.menu_item(im_str!("Redo"))
.shortcut(im_str!("CTRL+Y")) .shortcut(im_str!("CTRL+Y"))
.enabled(false) .enabled(false)
.build(); .build();
ui.separator(); ui.separator();
ui.menu_item(im_str!("Cut")) ui.menu_item(im_str!("Cut"))
.shortcut(im_str!("CTRL+X")) .shortcut(im_str!("CTRL+X"))
.build(); .build();
ui.menu_item(im_str!("Copy")) ui.menu_item(im_str!("Copy"))
.shortcut(im_str!("CTRL+C")) .shortcut(im_str!("CTRL+C"))
.build(); .build();
ui.menu_item(im_str!("Paste")) ui.menu_item(im_str!("Paste"))
.shortcut(im_str!("CTRL+V")) .shortcut(im_str!("CTRL+V"))
.build(); .build();
}); });
}); });
} }
fn show_example_menu_file<'a>(ui: &Ui<'a>, state: &mut FileMenuState) { fn show_example_menu_file<'a>(ui: &Ui<'a>, state: &mut FileMenuState) {
ui.menu_item(im_str!("(dummy menu)")) ui.menu_item(im_str!("(dummy menu)")).enabled(false).build();
.enabled(false)
.build();
ui.menu_item(im_str!("New")).build(); ui.menu_item(im_str!("New")).build();
ui.menu_item(im_str!("Open")) ui.menu_item(im_str!("Open"))
.shortcut(im_str!("Ctrl+O")) .shortcut(im_str!("Ctrl+O"))
.build(); .build();
ui.menu(im_str!("Open Recent")) ui.menu(im_str!("Open Recent")).build(|| {
.build(|| { ui.menu_item(im_str!("fish_hat.c")).build();
ui.menu_item(im_str!("fish_hat.c")).build(); ui.menu_item(im_str!("fish_hat.inl")).build();
ui.menu_item(im_str!("fish_hat.inl")).build(); ui.menu_item(im_str!("fish_hat.h")).build();
ui.menu_item(im_str!("fish_hat.h")).build(); ui.menu(im_str!("More..")).build(|| {
ui.menu(im_str!("More..")) ui.menu_item(im_str!("Hello")).build();
.build(|| { ui.menu_item(im_str!("Sailor")).build();
ui.menu_item(im_str!("Hello")).build(); ui.menu(im_str!("Recurse..")).build(|| {
ui.menu_item(im_str!("Sailor")).build(); show_example_menu_file(ui, state);
ui.menu(im_str!("Recurse..")) });
.build(|| { show_example_menu_file(ui, state); });
});
}); });
});
ui.menu_item(im_str!("Save")) ui.menu_item(im_str!("Save"))
.shortcut(im_str!("Ctrl+S")) .shortcut(im_str!("Ctrl+S"))
.build(); .build();
ui.menu_item(im_str!("Save As..")).build(); ui.menu_item(im_str!("Save As..")).build();
ui.separator(); ui.separator();
ui.menu(im_str!("Options")) ui.menu(im_str!("Options")).build(|| {
.build(|| { ui.menu_item(im_str!("Enabled"))
ui.menu_item(im_str!("Enabled")) .selected(&mut state.enabled)
.selected(&mut state.enabled) .build();
.build(); // TODO
// TODO });
}); ui.menu(im_str!("Colors")).build(|| {
ui.menu(im_str!("Colors")) // TODO
.build(|| { });
// TODO ui.menu(im_str!("Disabled")).enabled(false).build(|| {
}); unreachable!();
ui.menu(im_str!("Disabled")) });
.enabled(false)
.build(|| {
unreachable!();
});
let mut checked = true; let mut checked = true;
ui.menu_item(im_str!("Checked")) ui.menu_item(im_str!("Checked"))
.selected(&mut checked) .selected(&mut checked)
@ -491,9 +506,11 @@ fn show_example_app_auto_resize<'a>(ui: &Ui<'a>, state: &mut AutoResizeState, op
.opened(opened) .opened(opened)
.always_auto_resize(true) .always_auto_resize(true)
.build(|| { .build(|| {
ui.text(im_str!("Window will resize every-ui to the size of its content. ui.text(im_str!(
"Window will resize every-ui to the size of its content.
Note that you probably don't want to query the window size to Note that you probably don't want to query the window size to
output your content because that would create a feedback loop.")); output your content because that would create a feedback loop."
));
ui.slider_int(im_str!("Number of lines"), &mut state.lines, 1, 20) ui.slider_int(im_str!("Number of lines"), &mut state.lines, 1, 20)
.build(); .build();
for i in 0..state.lines { for i in 0..state.lines {
@ -511,26 +528,36 @@ fn show_example_app_fixed_overlay<'a>(ui: &Ui<'a>, opened: &mut bool) {
.movable(false) .movable(false)
.save_settings(false) .save_settings(false)
.build(|| { .build(|| {
ui.text(im_str!("Simple overlay\non the top-left side of the screen.")); ui.text(im_str!(
ui.separator(); "Simple overlay\non the top-left side of the screen."
let mouse_pos = ui.imgui().mouse_pos(); ));
ui.text(im_str!("Mouse Position: ({:.1},{:.1})", mouse_pos.0, mouse_pos.1)); ui.separator();
}) let mouse_pos = ui.imgui().mouse_pos();
ui.text(im_str!(
"Mouse Position: ({:.1},{:.1})",
mouse_pos.0,
mouse_pos.1
));
})
} }
fn show_example_app_manipulating_window_title<'a>(ui: &Ui<'a>) { fn show_example_app_manipulating_window_title<'a>(ui: &Ui<'a>) {
ui.window(im_str!("Same title as another window##1")) ui.window(im_str!("Same title as another window##1"))
.position((100.0, 100.0), ImGuiCond::FirstUseEver) .position((100.0, 100.0), ImGuiCond::FirstUseEver)
.build(|| { .build(|| {
ui.text(im_str!("This is window 1. ui.text(im_str!(
My title is the same as window 2, but my identifier is unique.")); "This is window 1.
}); My title is the same as window 2, but my identifier is unique."
));
});
ui.window(im_str!("Same title as another window##2")) ui.window(im_str!("Same title as another window##2"))
.position((100.0, 200.0), ImGuiCond::FirstUseEver) .position((100.0, 200.0), ImGuiCond::FirstUseEver)
.build(|| { .build(|| {
ui.text(im_str!("This is window 2. ui.text(im_str!(
My title is the same as window 1, but my identifier is unique.")); "This is window 2.
}); My title is the same as window 1, but my identifier is unique."
));
});
let chars = ['|', '/', '-', '\\']; let chars = ['|', '/', '-', '\\'];
let ch_idx = (ui.imgui().get_time() / 0.25) as usize & 3; let ch_idx = (ui.imgui().get_time() / 0.25) as usize & 3;
let num = ui.imgui().get_frame_count(); // The C++ version uses rand() here let num = ui.imgui().get_frame_count(); // The C++ version uses rand() here

View File

@ -14,7 +14,7 @@ pub enum RendererError {
Update(gfx::UpdateError<usize>), Update(gfx::UpdateError<usize>),
Buffer(gfx::buffer::CreationError), Buffer(gfx::buffer::CreationError),
Pipeline(gfx::PipelineStateError<String>), Pipeline(gfx::PipelineStateError<String>),
Combined(gfx::CombinedError) Combined(gfx::CombinedError),
} }
impl From<gfx::UpdateError<usize>> for RendererError { impl From<gfx::UpdateError<usize>> for RendererError {
@ -86,32 +86,50 @@ pub struct Renderer<R: Resources> {
} }
impl<R: Resources> Renderer<R> { impl<R: Resources> Renderer<R> {
pub fn init<F: Factory<R>>(imgui: &mut ImGui, pub fn init<F: Factory<R>>(
factory: &mut F, imgui: &mut ImGui,
shaders: Shaders, factory: &mut F,
out: RenderTargetView<R, gfx::format::Rgba8>) shaders: Shaders,
-> RendererResult<Renderer<R>> { out: RenderTargetView<R, gfx::format::Rgba8>,
) -> RendererResult<Renderer<R>> {
let (vs_code, ps_code) = shaders.get_program_code(); let (vs_code, ps_code) = shaders.get_program_code();
let pso = factory.create_pipeline_simple(vs_code, ps_code, pipe::new())?; let pso = factory.create_pipeline_simple(
let vertex_buffer = factory.create_buffer::<ImDrawVert>(256, vs_code,
gfx::buffer::Role::Vertex, ps_code,
gfx::memory::Usage::Dynamic, pipe::new(),
Bind::empty())?; )?;
let index_buffer = factory.create_buffer::<ImDrawIdx>(256, let vertex_buffer = factory.create_buffer::<ImDrawVert>(
gfx::buffer::Role::Index, 256,
gfx::memory::Usage::Dynamic, gfx::buffer::Role::Vertex,
Bind::empty())?; gfx::memory::Usage::Dynamic,
Bind::empty(),
)?;
let index_buffer = factory.create_buffer::<ImDrawIdx>(
256,
gfx::buffer::Role::Index,
gfx::memory::Usage::Dynamic,
Bind::empty(),
)?;
let (_, texture) = imgui.prepare_texture(|handle| { let (_, texture) = imgui.prepare_texture(|handle| {
factory.create_texture_immutable_u8::<gfx::format::Rgba8>(gfx::texture::Kind::D2(handle.width as u16, handle.height as u16, gfx::texture::AaMode::Single), &[handle.pixels]) factory.create_texture_immutable_u8::<gfx::format::Rgba8>(
gfx::texture::Kind::D2(
handle.width as u16,
handle.height as u16,
gfx::texture::AaMode::Single,
),
&[handle.pixels],
)
})?; })?;
// TODO: set texture id in imgui // TODO: set texture id in imgui
let sampler = factory.create_sampler_linear(); let sampler = factory.create_sampler_linear();
let data = pipe::Data { let data = pipe::Data {
vertex_buffer: vertex_buffer, vertex_buffer: vertex_buffer,
matrix: [[0.0, 0.0, 0.0, 0.0], matrix: [
[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, -1.0, 0.0], [0.0, 0.0, 0.0, 0.0],
[-1.0, 1.0, 0.0, 1.0]], [0.0, 0.0, -1.0, 0.0],
[-1.0, 1.0, 0.0, 1.0],
],
tex: (texture, sampler), tex: (texture, sampler),
out: out, out: out,
scissor: Rect { scissor: Rect {
@ -136,37 +154,51 @@ impl<R: Resources> Renderer<R> {
pub fn update_render_target(&mut self, out: RenderTargetView<R, gfx::format::Rgba8>) { pub fn update_render_target(&mut self, out: RenderTargetView<R, gfx::format::Rgba8>) {
self.bundle.data.out = out; self.bundle.data.out = out;
} }
pub fn render<'a, F: Factory<R>, C: CommandBuffer<R>>(&mut self, pub fn render<'a, F: Factory<R>, C: CommandBuffer<R>>(
ui: Ui<'a>, &mut self,
factory: &mut F, ui: Ui<'a>,
encoder: &mut Encoder<R, C>) factory: &mut F,
-> RendererResult<()> { encoder: &mut Encoder<R, C>,
) -> RendererResult<()> {
let (width, height) = ui.imgui().display_size(); let (width, height) = ui.imgui().display_size();
if width == 0.0 || height == 0.0 { if width == 0.0 || height == 0.0 {
return Ok(()); return Ok(());
} }
self.bundle.data.matrix = [[2.0 / width as f32, 0.0, 0.0, 0.0], self.bundle.data.matrix = [
[0.0, -2.0 / height as f32, 0.0, 0.0], [2.0 / width as f32, 0.0, 0.0, 0.0],
[0.0, 0.0, -1.0, 0.0], [0.0, -2.0 / height as f32, 0.0, 0.0],
[-1.0, 1.0, 0.0, 1.0]]; [0.0, 0.0, -1.0, 0.0],
[-1.0, 1.0, 0.0, 1.0],
];
ui.render(|ui, draw_list| self.render_draw_list(ui, factory, encoder, draw_list)) ui.render(|ui, draw_list| {
self.render_draw_list(ui, factory, encoder, draw_list)
})
} }
fn render_draw_list<'a, F: Factory<R>, C: CommandBuffer<R>>(&mut self, fn render_draw_list<'a, F: Factory<R>, C: CommandBuffer<R>>(
ui: &'a Ui<'a>, &mut self,
factory: &mut F, ui: &'a Ui<'a>,
encoder: &mut Encoder<R, C>, factory: &mut F,
draw_list: DrawList<'a>) encoder: &mut Encoder<R, C>,
-> RendererResult<()> { draw_list: DrawList<'a>,
) -> RendererResult<()> {
let (scale_width, scale_height) = ui.imgui().display_framebuffer_scale(); let (scale_width, scale_height) = ui.imgui().display_framebuffer_scale();
self.bundle.slice.start = 0; self.bundle.slice.start = 0;
for cmd in draw_list.cmd_buffer { for cmd in draw_list.cmd_buffer {
// TODO: check cmd.texture_id // TODO: check cmd.texture_id
self.upload_vertex_buffer(factory, encoder, draw_list.vtx_buffer)?; self.upload_vertex_buffer(
self.upload_index_buffer(factory, encoder, draw_list.idx_buffer)?; factory,
encoder,
draw_list.vtx_buffer,
)?;
self.upload_index_buffer(
factory,
encoder,
draw_list.idx_buffer,
)?;
self.bundle.slice.end = self.bundle.slice.start + cmd.elem_count; self.bundle.slice.end = self.bundle.slice.start + cmd.elem_count;
self.bundle.data.scissor = Rect { self.bundle.data.scissor = Rect {
@ -180,29 +212,39 @@ impl<R: Resources> Renderer<R> {
} }
Ok(()) Ok(())
} }
fn upload_vertex_buffer<F: Factory<R>, C: CommandBuffer<R>>(&mut self, fn upload_vertex_buffer<F: Factory<R>, C: CommandBuffer<R>>(
factory: &mut F, &mut self,
encoder: &mut Encoder<R, C>, factory: &mut F,
vtx_buffer: &[ImDrawVert]) encoder: &mut Encoder<R, C>,
-> RendererResult<()> { vtx_buffer: &[ImDrawVert],
) -> RendererResult<()> {
if self.bundle.data.vertex_buffer.len() < vtx_buffer.len() { if self.bundle.data.vertex_buffer.len() < vtx_buffer.len() {
self.bundle.data.vertex_buffer = factory.create_buffer::<ImDrawVert>(vtx_buffer.len(), self.bundle.data.vertex_buffer = factory.create_buffer::<ImDrawVert>(
gfx::buffer::Role::Vertex, vtx_buffer.len(),
gfx::memory::Usage::Dynamic, gfx::buffer::Role::Vertex,
Bind::empty())?; gfx::memory::Usage::Dynamic,
Bind::empty(),
)?;
} }
Ok(encoder.update_buffer(&self.bundle.data.vertex_buffer, vtx_buffer, 0)?) Ok(encoder.update_buffer(
&self.bundle.data.vertex_buffer,
vtx_buffer,
0,
)?)
} }
fn upload_index_buffer<F: Factory<R>, C: CommandBuffer<R>>(&mut self, fn upload_index_buffer<F: Factory<R>, C: CommandBuffer<R>>(
factory: &mut F, &mut self,
encoder: &mut Encoder<R, C>, factory: &mut F,
idx_buffer: &[ImDrawIdx]) encoder: &mut Encoder<R, C>,
-> RendererResult<()> { idx_buffer: &[ImDrawIdx],
) -> RendererResult<()> {
if self.index_buffer.len() < idx_buffer.len() { if self.index_buffer.len() < idx_buffer.len() {
self.index_buffer = factory.create_buffer::<ImDrawIdx>(idx_buffer.len(), self.index_buffer = factory.create_buffer::<ImDrawIdx>(
gfx::buffer::Role::Index, idx_buffer.len(),
gfx::memory::Usage::Dynamic, gfx::buffer::Role::Index,
Bind::empty())?; gfx::memory::Usage::Dynamic,
Bind::empty(),
)?;
self.bundle.slice.buffer = self.index_buffer.clone().into_index_buffer(factory); self.bundle.slice.buffer = self.index_buffer.clone().into_index_buffer(factory);
} }
Ok(encoder.update_buffer(&self.index_buffer, idx_buffer, 0)?) Ok(encoder.update_buffer(&self.index_buffer, idx_buffer, 0)?)

View File

@ -73,21 +73,30 @@ impl Renderer {
pub fn render<'a, S: Surface>(&mut self, surface: &mut S, ui: Ui<'a>) -> RendererResult<()> { pub fn render<'a, S: Surface>(&mut self, surface: &mut S, ui: Ui<'a>) -> RendererResult<()> {
let _ = self.ctx.insert_debug_marker("imgui-rs: starting rendering"); let _ = self.ctx.insert_debug_marker("imgui-rs: starting rendering");
let result = ui.render(|ui, draw_list| self.render_draw_list(surface, ui, draw_list)); let result = ui.render(|ui, draw_list| {
self.render_draw_list(surface, ui, draw_list)
});
let _ = self.ctx.insert_debug_marker("imgui-rs: rendering finished"); let _ = self.ctx.insert_debug_marker("imgui-rs: rendering finished");
result result
} }
fn render_draw_list<'a, S: Surface>(&mut self, fn render_draw_list<'a, S: Surface>(
surface: &mut S, &mut self,
ui: &'a Ui<'a>, surface: &mut S,
draw_list: DrawList<'a>) ui: &'a Ui<'a>,
-> RendererResult<()> { draw_list: DrawList<'a>,
) -> RendererResult<()> {
use glium::{Blend, DrawParameters, Rect}; use glium::{Blend, DrawParameters, Rect};
use glium::uniforms::{MinifySamplerFilter, MagnifySamplerFilter}; use glium::uniforms::{MinifySamplerFilter, MagnifySamplerFilter};
try!(self.device_objects.upload_vertex_buffer(&self.ctx, draw_list.vtx_buffer)); try!(self.device_objects.upload_vertex_buffer(
try!(self.device_objects.upload_index_buffer(&self.ctx, draw_list.idx_buffer)); &self.ctx,
draw_list.vtx_buffer,
));
try!(self.device_objects.upload_index_buffer(
&self.ctx,
draw_list.idx_buffer,
));
let (width, height) = ui.imgui().display_size(); let (width, height) = ui.imgui().display_size();
let (scale_width, scale_height) = ui.imgui().display_framebuffer_scale(); let (scale_width, scale_height) = ui.imgui().display_framebuffer_scale();
@ -96,10 +105,12 @@ impl Renderer {
return Ok(()); return Ok(());
} }
let matrix = [[2.0 / width as f32, 0.0, 0.0, 0.0], let matrix = [
[0.0, 2.0 / -(height as f32), 0.0, 0.0], [2.0 / width as f32, 0.0, 0.0, 0.0],
[0.0, 0.0, -1.0, 0.0], [0.0, 2.0 / -(height as f32), 0.0, 0.0],
[-1.0, 1.0, 0.0, 1.0]]; [0.0, 0.0, -1.0, 0.0],
[-1.0, 1.0, 0.0, 1.0],
];
let font_texture_id = self.device_objects.texture.get_id() as usize; let font_texture_id = self.device_objects.texture.get_id() as usize;
let mut idx_start = 0; let mut idx_start = 0;
@ -109,31 +120,32 @@ impl Renderer {
let idx_end = idx_start + cmd.elem_count as usize; let idx_end = idx_start + cmd.elem_count as usize;
try!(surface.draw(&self.device_objects.vertex_buffer, try!(
&self.device_objects surface.draw(
.index_buffer &self.device_objects.vertex_buffer,
.slice(idx_start..idx_end) &self.device_objects
.expect("Invalid index buffer range"), .index_buffer
&self.device_objects.program, .slice(idx_start..idx_end)
&uniform! { .expect("Invalid index buffer range"),
&self.device_objects.program,
&uniform! {
matrix: matrix, matrix: matrix,
tex: self.device_objects.texture.sampled() tex: self.device_objects.texture.sampled()
.magnify_filter(MagnifySamplerFilter::Nearest) .magnify_filter(MagnifySamplerFilter::Nearest)
.minify_filter(MinifySamplerFilter::Nearest), .minify_filter(MinifySamplerFilter::Nearest),
}, },
&DrawParameters { &DrawParameters {
blend: Blend::alpha_blending(), blend: Blend::alpha_blending(),
scissor: Some(Rect { scissor: Some(Rect {
left: (cmd.clip_rect.x * scale_width) as u32, left: (cmd.clip_rect.x * scale_width) as u32,
bottom: ((height - cmd.clip_rect.w) * scale_height) as u32, bottom: ((height - cmd.clip_rect.w) * scale_height) as u32,
width: ((cmd.clip_rect.z - cmd.clip_rect.x) * scale_width) as width: ((cmd.clip_rect.z - cmd.clip_rect.x) * scale_width) as u32,
u32, height: ((cmd.clip_rect.w - cmd.clip_rect.y) * scale_height) as u32,
height: ((cmd.clip_rect.w - cmd.clip_rect.y) * }),
scale_height) as ..DrawParameters::default()
u32, },
}), )
..DrawParameters::default() );
}));
idx_start = idx_end; idx_start = idx_end;
} }
@ -149,8 +161,9 @@ pub struct DeviceObjects {
texture: Texture2d, texture: Texture2d,
} }
fn compile_default_program<F: Facade>(ctx: &F) fn compile_default_program<F: Facade>(
-> Result<Program, program::ProgramChooserCreationError> { ctx: &F,
) -> Result<Program, program::ProgramChooserCreationError> {
program!( program!(
ctx, ctx,
400 => { 400 => {
@ -186,7 +199,11 @@ impl DeviceObjects {
use glium::texture::{ClientFormat, RawImage2d}; use glium::texture::{ClientFormat, RawImage2d};
let vertex_buffer = try!(VertexBuffer::empty_dynamic(ctx, 0)); let vertex_buffer = try!(VertexBuffer::empty_dynamic(ctx, 0));
let index_buffer = try!(IndexBuffer::empty_dynamic(ctx, PrimitiveType::TrianglesList, 0)); let index_buffer = try!(IndexBuffer::empty_dynamic(
ctx,
PrimitiveType::TrianglesList,
0,
));
let program = try!(compile_default_program(ctx)); let program = try!(compile_default_program(ctx));
let texture = try!(im_gui.prepare_texture(|handle| { let texture = try!(im_gui.prepare_texture(|handle| {
@ -207,35 +224,42 @@ impl DeviceObjects {
texture: texture, texture: texture,
}) })
} }
pub fn upload_vertex_buffer<F: Facade>(&mut self, pub fn upload_vertex_buffer<F: Facade>(
ctx: &F, &mut self,
vtx_buffer: &[ImDrawVert]) ctx: &F,
-> RendererResult<()> { vtx_buffer: &[ImDrawVert],
) -> RendererResult<()> {
self.vertex_buffer.invalidate(); self.vertex_buffer.invalidate();
if let Some(slice) = self.vertex_buffer.slice_mut(0..vtx_buffer.len()) { if let Some(slice) = self.vertex_buffer.slice_mut(0..vtx_buffer.len()) {
slice.write(vtx_buffer); slice.write(vtx_buffer);
return Ok(()); return Ok(());
} }
self.vertex_buffer = try!(VertexBuffer::dynamic(ctx, vtx_buffer)); self.vertex_buffer = try!(VertexBuffer::dynamic(ctx, vtx_buffer));
let _ = ctx.get_context() let _ = ctx.get_context().insert_debug_marker(&format!(
.insert_debug_marker(&format!("imgui-rs: resized vertex buffer to {} bytes", "imgui-rs: resized vertex buffer to {} bytes",
self.vertex_buffer.get_size())); self.vertex_buffer.get_size()
));
Ok(()) Ok(())
} }
pub fn upload_index_buffer<F: Facade>(&mut self, pub fn upload_index_buffer<F: Facade>(
ctx: &F, &mut self,
idx_buffer: &[ImDrawIdx]) ctx: &F,
-> RendererResult<()> { idx_buffer: &[ImDrawIdx],
) -> RendererResult<()> {
self.index_buffer.invalidate(); self.index_buffer.invalidate();
if let Some(slice) = self.index_buffer.slice_mut(0..idx_buffer.len()) { if let Some(slice) = self.index_buffer.slice_mut(0..idx_buffer.len()) {
slice.write(idx_buffer); slice.write(idx_buffer);
return Ok(()); return Ok(());
} }
self.index_buffer = self.index_buffer = try!(IndexBuffer::dynamic(
try!(IndexBuffer::dynamic(ctx, PrimitiveType::TrianglesList, idx_buffer)); ctx,
let _ = ctx.get_context() PrimitiveType::TrianglesList,
.insert_debug_marker(&format!("imgui-rs: resized index buffer to {} bytes", idx_buffer,
self.index_buffer.get_size())); ));
let _ = ctx.get_context().insert_debug_marker(&format!(
"imgui-rs: resized index buffer to {} bytes",
self.index_buffer.get_size()
));
Ok(()) Ok(())
} }
} }

View File

@ -20,7 +20,10 @@ impl Structure<Format> for ImDrawVert {
Some(s) if s.starts_with('.') => &s[1..], Some(s) if s.starts_with('.') => &s[1..],
_ => name, _ => name,
}; };
(sub_name, array_id * (mem::size_of::<ImDrawVert>() as ElemOffset)) (
sub_name,
array_id * (mem::size_of::<ImDrawVert>() as ElemOffset),
)
} }
None => (name, 0), None => (name, 0),
} }
@ -31,21 +34,21 @@ impl Structure<Format> for ImDrawVert {
Some(Element { Some(Element {
format: <ImVec2 as Formatted>::get_format(), format: <ImVec2 as Formatted>::get_format(),
offset: unsafe { mem::transmute::<_, usize>(&dummy.pos) } as ElemOffset + offset: unsafe { mem::transmute::<_, usize>(&dummy.pos) } as ElemOffset +
big_offset, big_offset,
}) })
} }
"uv" => { "uv" => {
Some(Element { Some(Element {
format: <ImVec2 as Formatted>::get_format(), format: <ImVec2 as Formatted>::get_format(),
offset: unsafe { mem::transmute::<_, usize>(&dummy.uv) } as ElemOffset + offset: unsafe { mem::transmute::<_, usize>(&dummy.uv) } as ElemOffset +
big_offset, big_offset,
}) })
} }
"col" => { "col" => {
Some(Element { Some(Element {
format: <[U8Norm; 4] as Formatted>::get_format(), format: <[U8Norm; 4] as Formatted>::get_format(),
offset: unsafe { mem::transmute::<_, usize>(&dummy.col) } as ElemOffset + offset: unsafe { mem::transmute::<_, usize>(&dummy.col) } as ElemOffset +
big_offset, big_offset,
}) })
} }
_ => None, _ => None,

File diff suppressed because it is too large Load Diff

View File

@ -107,7 +107,9 @@ impl<'ui, 'p> ChildFrame<'ui, 'p> {
// https://github.com/Gekkio/imgui-rs/pull/58 // https://github.com/Gekkio/imgui-rs/pull/58
let show_border = false; let show_border = false;
let render_child_frame = unsafe { imgui_sys::igBeginChild(self.name.as_ptr(), self.size, show_border, self.flags) }; let render_child_frame = unsafe {
imgui_sys::igBeginChild(self.name.as_ptr(), self.size, show_border, self.flags)
};
if render_child_frame { if render_child_frame {
f(); f();
} }

View File

@ -143,12 +143,14 @@ impl<'ui, 'p> InputText<'ui, 'p> {
pub fn build(self) -> bool { pub fn build(self) -> bool {
unsafe { unsafe {
imgui_sys::igInputText(self.label.as_ptr(), imgui_sys::igInputText(
self.buf.as_mut_ptr(), self.label.as_ptr(),
self.buf.capacity_with_nul(), self.buf.as_mut_ptr(),
self.flags, self.buf.capacity_with_nul(),
None, self.flags,
ptr::null_mut()) None,
ptr::null_mut(),
)
} }
} }
} }
@ -177,11 +179,13 @@ impl<'ui, 'p> InputInt<'ui, 'p> {
pub fn build(self) -> bool { pub fn build(self) -> bool {
unsafe { unsafe {
imgui_sys::igInputInt(self.label.as_ptr(), imgui_sys::igInputInt(
self.value as *mut i32, self.label.as_ptr(),
self.step, self.value as *mut i32,
self.step_fast, self.step,
self.flags) self.step_fast,
self.flags,
)
} }
} }
@ -215,12 +219,14 @@ impl<'ui, 'p> InputFloat<'ui, 'p> {
pub fn build(self) -> bool { pub fn build(self) -> bool {
unsafe { unsafe {
imgui_sys::igInputFloat(self.label.as_ptr(), imgui_sys::igInputFloat(
self.value as *mut f32, self.label.as_ptr(),
self.step, self.value as *mut f32,
self.step_fast, self.step,
self.decimal_precision, self.step_fast,
self.flags) self.decimal_precision,
self.flags,
)
} }
} }

View File

@ -9,25 +9,24 @@ use std::str;
use imgui_sys::ImGuiStyleVar; use imgui_sys::ImGuiStyleVar;
#[allow(deprecated)] #[allow(deprecated)]
pub use imgui_sys::{ImGuiInputTextFlags_AllowTabInput, pub use imgui_sys::{ImGuiInputTextFlags_AllowTabInput, ImGuiInputTextFlags_AlwaysInsertMode,
ImGuiInputTextFlags_AlwaysInsertMode, ImGuiInputTextFlags_AutoSelectAll, ImGuiInputTextFlags_AutoSelectAll, ImGuiInputTextFlags_CallbackAlways,
ImGuiInputTextFlags_CallbackAlways, ImGuiInputTextFlags_CallbackCharFilter, ImGuiInputTextFlags_CallbackCharFilter,
ImGuiInputTextFlags_CallbackCompletion, ImGuiInputTextFlags_CallbackHistory, ImGuiInputTextFlags_CallbackCompletion, ImGuiInputTextFlags_CallbackHistory,
ImGuiInputTextFlags_CharsDecimal, ImGuiInputTextFlags_CharsHexadecimal, ImGuiInputTextFlags_CharsDecimal, ImGuiInputTextFlags_CharsHexadecimal,
ImGuiInputTextFlags_CharsNoBlank, ImGuiInputTextFlags_CharsUppercase, ImGuiInputTextFlags_CharsNoBlank, ImGuiInputTextFlags_CharsUppercase,
ImGuiInputTextFlags_CtrlEnterForNewLine, ImGuiInputTextFlags_EnterReturnsTrue, ImGuiInputTextFlags_CtrlEnterForNewLine, ImGuiInputTextFlags_EnterReturnsTrue,
ImGuiInputTextFlags_NoHorizontalScroll, ImGuiInputTextFlags_Password, ImGuiInputTextFlags_NoHorizontalScroll, ImGuiInputTextFlags_Password,
ImGuiInputTextFlags_ReadOnly, ImGuiInputTextFlags_ReadOnly, ImGuiSelectableFlags_DontClosePopups,
ImGuiSelectableFlags_DontClosePopups, ImGuiSelectableFlags_SpanAllColumns, ImGuiSelectableFlags_SpanAllColumns, ImGuiSetCond_Always,
ImGuiSetCond_Always, ImGuiSetCond_Appearing, ImGuiSetCond_Appearing, ImGuiSetCond_FirstUseEver, ImGuiSetCond_Once,
ImGuiSetCond_FirstUseEver, ImGuiSetCond_Once,
ImGuiTreeNodeFlags_AllowOverlapMode, ImGuiTreeNodeFlags_Bullet, ImGuiTreeNodeFlags_AllowOverlapMode, ImGuiTreeNodeFlags_Bullet,
ImGuiTreeNodeFlags_CollapsingHeader, ImGuiTreeNodeFlags_DefaultOpen, ImGuiTreeNodeFlags_CollapsingHeader, ImGuiTreeNodeFlags_DefaultOpen,
ImGuiTreeNodeFlags_Framed, ImGuiTreeNodeFlags_Leaf, ImGuiTreeNodeFlags_Framed, ImGuiTreeNodeFlags_Leaf,
ImGuiTreeNodeFlags_NoAutoOpenOnLog, ImGuiTreeNodeFlags_NoTreePushOnOpen, ImGuiTreeNodeFlags_NoAutoOpenOnLog, ImGuiTreeNodeFlags_NoTreePushOnOpen,
ImGuiTreeNodeFlags_OpenOnArrow, ImGuiTreeNodeFlags_OpenOnDoubleClick, ImGuiTreeNodeFlags_OpenOnArrow, ImGuiTreeNodeFlags_OpenOnDoubleClick,
ImGuiTreeNodeFlags_Selected, ImGuiTreeNodeFlags_Selected, ImGuiWindowFlags_AlwaysAutoResize,
ImGuiWindowFlags_AlwaysAutoResize, ImGuiWindowFlags_AlwaysHorizontalScrollbar, ImGuiWindowFlags_AlwaysHorizontalScrollbar,
ImGuiWindowFlags_AlwaysUseWindowPadding, ImGuiWindowFlags_AlwaysUseWindowPadding,
ImGuiWindowFlags_AlwaysVerticalScrollbar, ImGuiWindowFlags_AlwaysVerticalScrollbar,
ImGuiWindowFlags_HorizontalScrollbar, ImGuiWindowFlags_MenuBar, ImGuiWindowFlags_HorizontalScrollbar, ImGuiWindowFlags_MenuBar,
@ -39,10 +38,11 @@ pub use imgui_sys::{ImGuiInputTextFlags_AllowTabInput,
ImGuiWindowFlags_ShowBorders}; ImGuiWindowFlags_ShowBorders};
pub use imgui_sys::{ImDrawIdx, ImDrawVert, ImGuiInputTextFlags, ImGuiKey, ImGuiSelectableFlags, pub use imgui_sys::{ImDrawIdx, ImDrawVert, ImGuiInputTextFlags, ImGuiKey, ImGuiSelectableFlags,
ImGuiCond, ImGuiCol, ImGuiStyle, ImGuiTreeNodeFlags, ImGuiWindowFlags, ImGuiCond, ImGuiCol, ImGuiStyle, ImGuiTreeNodeFlags, ImGuiWindowFlags, ImVec2,
ImVec2, ImVec4}; ImVec4};
pub use child_frame::ChildFrame; pub use child_frame::ChildFrame;
pub use input::{InputFloat, InputFloat2, InputFloat3, InputFloat4, InputInt, InputInt2, InputInt3, InputInt4, InputText}; pub use input::{InputFloat, InputFloat2, InputFloat3, InputFloat4, InputInt, InputInt2, InputInt3,
InputInt4, InputText};
pub use menus::{Menu, MenuItem}; pub use menus::{Menu, MenuItem};
pub use plothistogram::PlotHistogram; pub use plothistogram::PlotHistogram;
pub use plotlines::PlotLines; pub use plotlines::PlotLines;
@ -113,7 +113,8 @@ impl ImGui {
pub fn style(&self) -> &ImGuiStyle { unsafe { &*imgui_sys::igGetStyle() } } pub fn style(&self) -> &ImGuiStyle { unsafe { &*imgui_sys::igGetStyle() } }
pub fn style_mut(&mut self) -> &mut ImGuiStyle { unsafe { &mut *imgui_sys::igGetStyle() } } pub fn style_mut(&mut self) -> &mut ImGuiStyle { unsafe { &mut *imgui_sys::igGetStyle() } }
pub fn prepare_texture<'a, F, T>(&mut self, f: F) -> T pub fn prepare_texture<'a, F, T>(&mut self, f: F) -> T
where F: FnOnce(TextureHandle<'a>) -> T where
F: FnOnce(TextureHandle<'a>) -> T,
{ {
let io = self.io(); let io = self.io();
let mut pixels: *mut c_uchar = ptr::null_mut(); let mut pixels: *mut c_uchar = ptr::null_mut();
@ -121,17 +122,18 @@ impl ImGui {
let mut height: c_int = 0; let mut height: c_int = 0;
let mut bytes_per_pixel: c_int = 0; let mut bytes_per_pixel: c_int = 0;
unsafe { unsafe {
imgui_sys::ImFontAtlas_GetTexDataAsRGBA32(io.fonts, imgui_sys::ImFontAtlas_GetTexDataAsRGBA32(
&mut pixels, io.fonts,
&mut width, &mut pixels,
&mut height, &mut width,
&mut bytes_per_pixel); &mut height,
&mut bytes_per_pixel,
);
f(TextureHandle { f(TextureHandle {
width: width as u32, width: width as u32,
height: height as u32, height: height as u32,
pixels: slice::from_raw_parts(pixels, pixels: slice::from_raw_parts(pixels, (width * height * bytes_per_pixel) as usize),
(width * height * bytes_per_pixel) as usize), })
})
} }
} }
pub fn set_texture_id(&mut self, value: usize) { pub fn set_texture_id(&mut self, value: usize) {
@ -193,7 +195,10 @@ impl ImGui {
} }
pub fn display_framebuffer_scale(&self) -> (f32, f32) { pub fn display_framebuffer_scale(&self) -> (f32, f32) {
let io = self.io(); let io = self.io();
(io.display_framebuffer_scale.x, io.display_framebuffer_scale.y) (
io.display_framebuffer_scale.x,
io.display_framebuffer_scale.y,
)
} }
pub fn mouse_pos(&self) -> (f32, f32) { pub fn mouse_pos(&self) -> (f32, f32) {
let io = self.io(); let io = self.io();
@ -250,11 +255,12 @@ impl ImGui {
pub fn get_time(&self) -> f32 { unsafe { imgui_sys::igGetTime() } } pub fn get_time(&self) -> f32 { unsafe { imgui_sys::igGetTime() } }
pub fn get_frame_count(&self) -> i32 { unsafe { imgui_sys::igGetFrameCount() } } pub fn get_frame_count(&self) -> i32 { unsafe { imgui_sys::igGetFrameCount() } }
pub fn get_frame_rate(&self) -> f32 { self.io().framerate } pub fn get_frame_rate(&self) -> f32 { self.io().framerate }
pub fn frame<'ui, 'a: 'ui>(&'a mut self, pub fn frame<'ui, 'a: 'ui>(
size_points: (u32, u32), &'a mut self,
size_pixels: (u32, u32), size_points: (u32, u32),
delta_time: f32) size_pixels: (u32, u32),
-> Ui<'ui> { delta_time: f32,
) -> Ui<'ui> {
{ {
let io = self.io_mut(); let io = self.io_mut();
io.display_size.x = size_points.0 as c_float; io.display_size.x = size_points.0 as c_float;
@ -335,7 +341,8 @@ impl<'ui> Ui<'ui> {
io.metrics_active_windows io.metrics_active_windows
} }
pub fn render<F, E>(self, mut f: F) -> Result<(), E> pub fn render<F, E>(self, mut f: F) -> Result<(), E>
where F: FnMut(&Ui, DrawList) -> Result<(), E> where
F: FnMut(&Ui, DrawList) -> Result<(), E>,
{ {
unsafe { unsafe {
imgui_sys::igRender(); imgui_sys::igRender();
@ -396,7 +403,8 @@ impl<'ui> Ui<'ui> {
/// Runs a function after temporarily pushing a value to the item width stack. /// Runs a function after temporarily pushing a value to the item width stack.
pub fn with_item_width<F>(&self, width: f32, f: F) pub fn with_item_width<F>(&self, width: f32, f: F)
where F: FnOnce() where
F: FnOnce(),
{ {
self.push_item_width(width); self.push_item_width(width);
f(); f();
@ -447,7 +455,8 @@ impl<'ui> Ui<'ui> {
/// Runs a function after temporarily pushing a value to the ID stack. /// Runs a function after temporarily pushing a value to the ID stack.
pub fn with_id<F>(&self, id: i32, f: F) pub fn with_id<F>(&self, id: i32, f: F)
where F: FnOnce() where
F: FnOnce(),
{ {
self.push_id(id); self.push_id(id);
f(); f();
@ -464,7 +473,8 @@ impl<'ui> Ui<'ui> {
} }
} }
pub fn text_colored<'p, A>(&self, col: A, text: &'p ImStr) pub fn text_colored<'p, A>(&self, col: A, text: &'p ImStr)
where A: Into<ImVec4> where
A: Into<ImVec4>,
{ {
unsafe { unsafe {
imgui_sys::igTextColored(col.into(), fmt_ptr(), text.as_ptr()); imgui_sys::igTextColored(col.into(), fmt_ptr(), text.as_ptr());
@ -514,22 +524,25 @@ impl<'ui> Ui<'ui> {
pub fn input_float<'p>(&self, label: &'p ImStr, value: &'p mut f32) -> InputFloat<'ui, 'p> { pub fn input_float<'p>(&self, label: &'p ImStr, value: &'p mut f32) -> InputFloat<'ui, 'p> {
InputFloat::new(self, label, value) InputFloat::new(self, label, value)
} }
pub fn input_float2<'p>(&self, pub fn input_float2<'p>(
label: &'p ImStr, &self,
value: &'p mut [f32; 2]) label: &'p ImStr,
-> InputFloat2<'ui, 'p> { value: &'p mut [f32; 2],
) -> InputFloat2<'ui, 'p> {
InputFloat2::new(self, label, value) InputFloat2::new(self, label, value)
} }
pub fn input_float3<'p>(&self, pub fn input_float3<'p>(
label: &'p ImStr, &self,
value: &'p mut [f32; 3]) label: &'p ImStr,
-> InputFloat3<'ui, 'p> { value: &'p mut [f32; 3],
) -> InputFloat3<'ui, 'p> {
InputFloat3::new(self, label, value) InputFloat3::new(self, label, value)
} }
pub fn input_float4<'p>(&self, pub fn input_float4<'p>(
label: &'p ImStr, &self,
value: &'p mut [f32; 4]) label: &'p ImStr,
-> InputFloat4<'ui, 'p> { value: &'p mut [f32; 4],
) -> InputFloat4<'ui, 'p> {
InputFloat4::new(self, label, value) InputFloat4::new(self, label, value)
} }
pub fn input_int<'p>(&self, label: &'p ImStr, value: &'p mut i32) -> InputInt<'ui, 'p> { pub fn input_int<'p>(&self, label: &'p ImStr, value: &'p mut i32) -> InputInt<'ui, 'p> {
@ -548,68 +561,76 @@ impl<'ui> Ui<'ui> {
// Widgets: Sliders // Widgets: Sliders
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
pub fn slider_float<'p>(&self, pub fn slider_float<'p>(
label: &'p ImStr, &self,
value: &'p mut f32, label: &'p ImStr,
min: f32, value: &'p mut f32,
max: f32) min: f32,
-> SliderFloat<'ui, 'p> { max: f32,
) -> SliderFloat<'ui, 'p> {
SliderFloat::new(self, label, value, min, max) SliderFloat::new(self, label, value, min, max)
} }
pub fn slider_float2<'p>(&self, pub fn slider_float2<'p>(
label: &'p ImStr, &self,
value: &'p mut [f32; 2], label: &'p ImStr,
min: f32, value: &'p mut [f32; 2],
max: f32) min: f32,
-> SliderFloat2<'ui, 'p> { max: f32,
) -> SliderFloat2<'ui, 'p> {
SliderFloat2::new(self, label, value, min, max) SliderFloat2::new(self, label, value, min, max)
} }
pub fn slider_float3<'p>(&self, pub fn slider_float3<'p>(
label: &'p ImStr, &self,
value: &'p mut [f32; 3], label: &'p ImStr,
min: f32, value: &'p mut [f32; 3],
max: f32) min: f32,
-> SliderFloat3<'ui, 'p> { max: f32,
) -> SliderFloat3<'ui, 'p> {
SliderFloat3::new(self, label, value, min, max) SliderFloat3::new(self, label, value, min, max)
} }
pub fn slider_float4<'p>(&self, pub fn slider_float4<'p>(
label: &'p ImStr, &self,
value: &'p mut [f32; 4], label: &'p ImStr,
min: f32, value: &'p mut [f32; 4],
max: f32) min: f32,
-> SliderFloat4<'ui, 'p> { max: f32,
) -> SliderFloat4<'ui, 'p> {
SliderFloat4::new(self, label, value, min, max) SliderFloat4::new(self, label, value, min, max)
} }
pub fn slider_int<'p>(&self, pub fn slider_int<'p>(
label: &'p ImStr, &self,
value: &'p mut i32, label: &'p ImStr,
min: i32, value: &'p mut i32,
max: i32) min: i32,
-> SliderInt<'ui, 'p> { max: i32,
) -> SliderInt<'ui, 'p> {
SliderInt::new(self, label, value, min, max) SliderInt::new(self, label, value, min, max)
} }
pub fn slider_int2<'p>(&self, pub fn slider_int2<'p>(
label: &'p ImStr, &self,
value: &'p mut [i32; 2], label: &'p ImStr,
min: i32, value: &'p mut [i32; 2],
max: i32) min: i32,
-> SliderInt2<'ui, 'p> { max: i32,
) -> SliderInt2<'ui, 'p> {
SliderInt2::new(self, label, value, min, max) SliderInt2::new(self, label, value, min, max)
} }
pub fn slider_int3<'p>(&self, pub fn slider_int3<'p>(
label: &'p ImStr, &self,
value: &'p mut [i32; 3], label: &'p ImStr,
min: i32, value: &'p mut [i32; 3],
max: i32) min: i32,
-> SliderInt3<'ui, 'p> { max: i32,
) -> SliderInt3<'ui, 'p> {
SliderInt3::new(self, label, value, min, max) SliderInt3::new(self, label, value, min, max)
} }
pub fn slider_int4<'p>(&self, pub fn slider_int4<'p>(
label: &'p ImStr, &self,
value: &'p mut [i32; 4], label: &'p ImStr,
min: i32, value: &'p mut [i32; 4],
max: i32) min: i32,
-> SliderInt4<'ui, 'p> { max: i32,
) -> SliderInt4<'ui, 'p> {
SliderInt4::new(self, label, value, min, max) SliderInt4::new(self, label, value, min, max)
} }
} }
@ -624,12 +645,13 @@ impl<'ui> Ui<'ui> {
// Widgets: Selectable / Lists // Widgets: Selectable / Lists
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
pub fn selectable<'p, S: Into<ImVec2>>(&self, pub fn selectable<'p, S: Into<ImVec2>>(
label: &'p ImStr, &self,
selected: bool, label: &'p ImStr,
flags: ImGuiSelectableFlags, selected: bool,
size: S) flags: ImGuiSelectableFlags,
-> bool { size: S,
) -> bool {
unsafe { imgui_sys::igSelectable(label.as_ptr(), selected, flags, size.into()) } unsafe { imgui_sys::igSelectable(label.as_ptr(), selected, flags, size.into()) }
} }
} }
@ -637,7 +659,8 @@ impl<'ui> Ui<'ui> {
// Widgets: Menus // Widgets: Menus
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
pub fn main_menu_bar<F>(&self, f: F) pub fn main_menu_bar<F>(&self, f: F)
where F: FnOnce() where
F: FnOnce(),
{ {
let render = unsafe { imgui_sys::igBeginMainMenuBar() }; let render = unsafe { imgui_sys::igBeginMainMenuBar() };
if render { if render {
@ -646,7 +669,8 @@ impl<'ui> Ui<'ui> {
} }
} }
pub fn menu_bar<F>(&self, f: F) pub fn menu_bar<F>(&self, f: F)
where F: FnOnce() where
F: FnOnce(),
{ {
let render = unsafe { imgui_sys::igBeginMenuBar() }; let render = unsafe { imgui_sys::igBeginMenuBar() };
if render { if render {
@ -655,7 +679,9 @@ impl<'ui> Ui<'ui> {
} }
} }
pub fn menu<'p>(&self, label: &'p ImStr) -> Menu<'ui, 'p> { Menu::new(self, label) } pub fn menu<'p>(&self, label: &'p ImStr) -> Menu<'ui, 'p> { Menu::new(self, label) }
pub fn menu_item<'p>(&self, label: &'p ImStr) -> MenuItem<'ui, 'p> { MenuItem::new(self, label) } pub fn menu_item<'p>(&self, label: &'p ImStr) -> MenuItem<'ui, 'p> {
MenuItem::new(self, label)
}
} }
// Widgets: Popups // Widgets: Popups
@ -664,7 +690,8 @@ impl<'ui> Ui<'ui> {
unsafe { imgui_sys::igOpenPopup(str_id.as_ptr()) }; unsafe { imgui_sys::igOpenPopup(str_id.as_ptr()) };
} }
pub fn popup<'p, F>(&self, str_id: &'p ImStr, f: F) pub fn popup<'p, F>(&self, str_id: &'p ImStr, f: F)
where F: FnOnce() where
F: FnOnce(),
{ {
let render = unsafe { imgui_sys::igBeginPopup(str_id.as_ptr()) }; let render = unsafe { imgui_sys::igBeginPopup(str_id.as_ptr()) };
if render { if render {
@ -677,38 +704,44 @@ impl<'ui> Ui<'ui> {
// Widgets: Combos // Widgets: Combos
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
pub fn combo<'p>(&self, pub fn combo<'p>(
label: &'p ImStr, &self,
current_item: &mut i32, label: &'p ImStr,
items: &'p [&'p ImStr], current_item: &mut i32,
height_in_items: i32) items: &'p [&'p ImStr],
-> bool { height_in_items: i32,
) -> bool {
let items_inner: Vec<*const c_char> = items.into_iter().map(|item| item.as_ptr()).collect(); let items_inner: Vec<*const c_char> = items.into_iter().map(|item| item.as_ptr()).collect();
unsafe { unsafe {
imgui_sys::igCombo(label.as_ptr(), imgui_sys::igCombo(
current_item, label.as_ptr(),
items_inner.as_ptr() as *mut *const c_char, current_item,
items_inner.len() as i32, items_inner.as_ptr() as *mut *const c_char,
height_in_items) items_inner.len() as i32,
height_in_items,
)
} }
} }
} }
// Widgets: ListBox // Widgets: ListBox
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
pub fn list_box<'p>(&self, pub fn list_box<'p>(
label: &'p ImStr, &self,
current_item: &mut i32, label: &'p ImStr,
items: &'p [&'p ImStr], current_item: &mut i32,
height_in_items: i32) items: &'p [&'p ImStr],
-> bool { height_in_items: i32,
) -> bool {
let items_inner: Vec<*const c_char> = items.into_iter().map(|item| item.as_ptr()).collect(); let items_inner: Vec<*const c_char> = items.into_iter().map(|item| item.as_ptr()).collect();
unsafe { unsafe {
imgui_sys::igListBox(label.as_ptr(), imgui_sys::igListBox(
current_item, label.as_ptr(),
items_inner.as_ptr() as *mut *const c_char, current_item,
items_inner.len() as i32, items_inner.as_ptr() as *mut *const c_char,
height_in_items) items_inner.len() as i32,
height_in_items,
)
} }
} }
} }
@ -728,13 +761,8 @@ impl<'ui> Ui<'ui> {
/// ui.radio_button(im_str!("Item 2"), &mut selected_radio_value, 2); /// ui.radio_button(im_str!("Item 2"), &mut selected_radio_value, 2);
/// ui.radio_button(im_str!("Item 3"), &mut selected_radio_value, 3); /// ui.radio_button(im_str!("Item 3"), &mut selected_radio_value, 3);
/// ``` /// ```
pub fn radio_button<'p>(&self, pub fn radio_button<'p>(&self, label: &'p ImStr, value: &'p mut i32, wanted: i32) -> bool {
label: &'p ImStr, unsafe { imgui_sys::igRadioButton(label.as_ptr(), value, wanted) }
value: &'p mut i32,
wanted: i32) -> bool {
unsafe {
imgui_sys::igRadioButton(label.as_ptr(), value, wanted)
}
} }
/// Creates a radio button that shows as selected if the given value is true. /// Creates a radio button that shows as selected if the given value is true.
@ -754,9 +782,7 @@ impl<'ui> Ui<'ui> {
/// } /// }
/// ``` /// ```
pub fn radio_button_bool<'p>(&self, label: &'p ImStr, value: bool) -> bool { pub fn radio_button_bool<'p>(&self, label: &'p ImStr, value: bool) -> bool {
unsafe { unsafe { imgui_sys::igRadioButtonBool(label.as_ptr(), value) }
imgui_sys::igRadioButtonBool(label.as_ptr(), value)
}
} }
} }
@ -767,7 +793,11 @@ impl<'ui> Ui<'ui> {
} }
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
pub fn plot_histogram<'p>(&self, label: &'p ImStr, values: &'p [f32]) -> PlotHistogram<'ui, 'p> { pub fn plot_histogram<'p>(
&self,
label: &'p ImStr,
values: &'p [f32],
) -> PlotHistogram<'ui, 'p> {
PlotHistogram::new(self, label, values) PlotHistogram::new(self, label, values)
} }
} }
@ -779,9 +809,22 @@ impl<'ui> Ui<'ui> {
/// This is a feature of imgui. /// This is a feature of imgui.
/// ///
/// wrap_width allows you to request a width at which to wrap the text to a newline for the calculation. /// wrap_width allows you to request a width at which to wrap the text to a newline for the calculation.
pub fn calc_text_size(&self, text: &ImStr, hide_text_after_double_hash: bool, wrap_width: f32) -> ImVec2 { pub fn calc_text_size(
&self,
text: &ImStr,
hide_text_after_double_hash: bool,
wrap_width: f32,
) -> ImVec2 {
let mut buffer = ImVec2::new(0.0, 0.0); let mut buffer = ImVec2::new(0.0, 0.0);
unsafe { imgui_sys::igCalcTextSize(&mut buffer as *mut ImVec2, text.as_ptr(), std::ptr::null(), hide_text_after_double_hash, wrap_width); } unsafe {
imgui_sys::igCalcTextSize(
&mut buffer as *mut ImVec2,
text.as_ptr(),
std::ptr::null(),
hide_text_after_double_hash,
wrap_width,
);
}
buffer buffer
} }
} }
@ -799,31 +842,39 @@ impl<'ui> Ui<'ui> {
/// .overlay_text(im_str!("Progress!")) /// .overlay_text(im_str!("Progress!"))
/// .build(); /// .build();
/// ``` /// ```
pub fn progress_bar<'p>(&self, fraction: f32) -> ProgressBar<'ui, 'p> { ProgressBar::new(self, fraction) } pub fn progress_bar<'p>(&self, fraction: f32) -> ProgressBar<'ui, 'p> {
ProgressBar::new(self, fraction)
}
} }
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
/// Creates a child frame. Size is size of child_frame within parent window. /// Creates a child frame. Size is size of child_frame within parent window.
/// ///
/// # Example /// # Example
/// ```rust,no_run /// ```rust,no_run
/// # use imgui::*; /// # use imgui::*;
/// # let mut imgui = ImGui::init(); /// # let mut imgui = ImGui::init();
/// # let ui = imgui.frame((0, 0), (0, 0), 0.1); /// # let ui = imgui.frame((0, 0), (0, 0), 0.1);
/// ui.window(im_str!("ChatWindow")) /// ui.window(im_str!("ChatWindow"))
/// .title_bar(true) /// .title_bar(true)
/// .scrollable(false) /// .scrollable(false)
/// .build(|| { /// .build(|| {
/// ui.separator(); /// ui.separator();
/// ///
/// ui.child_frame(im_str!("child frame"), (400.0, 100.0)) /// ui.child_frame(im_str!("child frame"), (400.0, 100.0))
/// .show_borders(true) /// .show_borders(true)
/// .always_show_vertical_scroll_bar(true) /// .always_show_vertical_scroll_bar(true)
/// .build(|| { /// .build(|| {
/// ui.text_colored((1.0, 0.0, 0.0, 1.0), im_str!("hello mate!")); /// ui.text_colored((1.0, 0.0, 0.0, 1.0), im_str!("hello mate!"));
/// }); /// });
/// }); /// });
pub fn child_frame<'p, S: Into<ImVec2>>(&self, name: &'p ImStr, size: S) -> ChildFrame<'ui, 'p> { ChildFrame::new(self, name, size.into()) } pub fn child_frame<'p, S: Into<ImVec2>>(
&self,
name: &'p ImStr,
size: S,
) -> ChildFrame<'ui, 'p> {
ChildFrame::new(self, name, size.into())
}
} }
impl<'ui> Ui<'ui> { impl<'ui> Ui<'ui> {
@ -877,14 +928,16 @@ impl<'ui> Ui<'ui> {
WindowPadding(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::WindowPadding, v) }, WindowPadding(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::WindowPadding, v) },
WindowRounding(v) => unsafe { igPushStyleVar(ImGuiStyleVar::WindowRounding, v) }, WindowRounding(v) => unsafe { igPushStyleVar(ImGuiStyleVar::WindowRounding, v) },
WindowMinSize(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::WindowMinSize, v) }, WindowMinSize(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::WindowMinSize, v) },
ChildWindowRounding(v) => unsafe { igPushStyleVar(ImGuiStyleVar::ChildWindowRounding, v) }, ChildWindowRounding(v) => unsafe {
igPushStyleVar(ImGuiStyleVar::ChildWindowRounding, v)
},
FramePadding(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::FramePadding, v) }, FramePadding(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::FramePadding, v) },
FrameRounding(v) => unsafe { igPushStyleVar(ImGuiStyleVar::FrameRounding, v) }, FrameRounding(v) => unsafe { igPushStyleVar(ImGuiStyleVar::FrameRounding, v) },
ItemSpacing(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::ItemSpacing, v) }, ItemSpacing(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::ItemSpacing, v) },
ItemInnerSpacing(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::ItemInnerSpacing, v) }, ItemInnerSpacing(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::ItemInnerSpacing, v) },
IndentSpacing(v) => unsafe { igPushStyleVar(ImGuiStyleVar::IndentSpacing, v) }, IndentSpacing(v) => unsafe { igPushStyleVar(ImGuiStyleVar::IndentSpacing, v) },
GrabMinSize(v) => unsafe { igPushStyleVar(ImGuiStyleVar::GrabMinSize, v) }, GrabMinSize(v) => unsafe { igPushStyleVar(ImGuiStyleVar::GrabMinSize, v) },
ButtonTextAlign(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::ButtonTextAlign, v) } ButtonTextAlign(v) => unsafe { igPushStyleVarVec(ImGuiStyleVar::ButtonTextAlign, v) },
} }
} }
} }
@ -901,10 +954,19 @@ impl<'ui> Ui<'ui> {
/// ui.text_wrapped(im_str!("AB")); /// ui.text_wrapped(im_str!("AB"));
/// }); /// });
/// ``` /// ```
pub fn with_color_var<F: FnOnce(), C: Into<ImVec4> + Copy>(&self, var: ImGuiCol, color: C, f: F) { pub fn with_color_var<F: FnOnce(), C: Into<ImVec4> + Copy>(
unsafe { imgui_sys::igPushStyleColor(var, color.into()); } &self,
var: ImGuiCol,
color: C,
f: F,
) {
unsafe {
imgui_sys::igPushStyleColor(var, color.into());
}
f(); f();
unsafe {imgui_sys::igPopStyleColor(1); } unsafe {
imgui_sys::igPopStyleColor(1);
}
} }
/// Runs a function after temporarily pushing an array of values to the color stack. /// Runs a function after temporarily pushing an array of values to the color stack.
@ -921,9 +983,15 @@ impl<'ui> Ui<'ui> {
/// ui.text_wrapped(im_str!("AB")); /// ui.text_wrapped(im_str!("AB"));
/// }); /// });
/// ``` /// ```
pub fn with_color_vars<F: FnOnce(), C: Into<ImVec4> + Copy>(&self, color_vars: &[(ImGuiCol, C)], f: F) { pub fn with_color_vars<F: FnOnce(), C: Into<ImVec4> + Copy>(
&self,
color_vars: &[(ImGuiCol, C)],
f: F,
) {
for &(color_var, color) in color_vars { for &(color_var, color) in color_vars {
unsafe { imgui_sys::igPushStyleColor(color_var, color.into()); } unsafe {
imgui_sys::igPushStyleColor(color_var, color.into());
}
} }
f(); f();
unsafe { imgui_sys::igPopStyleColor(color_vars.len() as i32) }; unsafe { imgui_sys::igPopStyleColor(color_vars.len() as i32) };

View File

@ -70,9 +70,9 @@ impl<'ui, 'p> MenuItem<'ui, 'p> {
pub fn build(self) -> bool { pub fn build(self) -> bool {
let label = self.label.as_ptr(); let label = self.label.as_ptr();
let shortcut = self.shortcut.map(|x| x.as_ptr()).unwrap_or(ptr::null()); let shortcut = self.shortcut.map(|x| x.as_ptr()).unwrap_or(ptr::null());
let selected = self.selected let selected = self.selected.map(|x| x as *mut bool).unwrap_or(
.map(|x| x as *mut bool) ptr::null_mut(),
.unwrap_or(ptr::null_mut()); );
let enabled = self.enabled; let enabled = self.enabled;
unsafe { imgui_sys::igMenuItemPtr(label, shortcut, selected, enabled) } unsafe { imgui_sys::igMenuItemPtr(label, shortcut, selected, enabled) }
} }

View File

@ -63,17 +63,17 @@ impl<'ui, 'p> PlotHistogram<'ui, 'p> {
pub fn build(self) { pub fn build(self) {
unsafe { unsafe {
imgui_sys::igPlotHistogram(self.label.as_ptr(), imgui_sys::igPlotHistogram(
self.values.as_ptr() as *const c_float, self.label.as_ptr(),
self.values.len() as i32, self.values.as_ptr() as *const c_float,
self.values_offset as i32, self.values.len() as i32,
self.overlay_text self.values_offset as i32,
.map(|x| x.as_ptr()) self.overlay_text.map(|x| x.as_ptr()).unwrap_or(ptr::null()),
.unwrap_or(ptr::null()), self.scale_min,
self.scale_min, self.scale_max,
self.scale_max, self.graph_size,
self.graph_size, mem::size_of::<f32>() as i32,
mem::size_of::<f32>() as i32); );
} }
} }
} }

View File

@ -63,17 +63,17 @@ impl<'ui, 'p> PlotLines<'ui, 'p> {
pub fn build(self) { pub fn build(self) {
unsafe { unsafe {
imgui_sys::igPlotLines(self.label.as_ptr(), imgui_sys::igPlotLines(
self.values.as_ptr() as *const c_float, self.label.as_ptr(),
self.values.len() as i32, self.values.as_ptr() as *const c_float,
self.values_offset as i32, self.values.len() as i32,
self.overlay_text self.values_offset as i32,
.map(|x| x.as_ptr()) self.overlay_text.map(|x| x.as_ptr()).unwrap_or(ptr::null()),
.unwrap_or(ptr::null()), self.scale_min,
self.scale_min, self.scale_max,
self.scale_max, self.graph_size,
self.graph_size, mem::size_of::<f32>() as i32,
mem::size_of::<f32>() as i32); );
} }
} }
} }

View File

@ -49,11 +49,11 @@ impl<'ui, 'p> ProgressBar<'ui, 'p> {
/// of the progress bar, otherwise the it will not be shown. /// of the progress bar, otherwise the it will not be shown.
pub fn build(self) { pub fn build(self) {
unsafe { unsafe {
imgui_sys::igProgressBar(self.fraction, imgui_sys::igProgressBar(
&self.size, self.fraction,
self.overlay_text &self.size,
.map(|x| x.as_ptr()) self.overlay_text.map(|x| x.as_ptr()).unwrap_or(ptr::null()),
.unwrap_or(ptr::null())); );
} }
} }
} }

View File

@ -33,11 +33,13 @@ impl<'ui, 'p> SliderInt<'ui, 'p> {
} }
pub fn build(self) -> bool { pub fn build(self) -> bool {
unsafe { unsafe {
imgui_sys::igSliderInt(self.label.as_ptr(), imgui_sys::igSliderInt(
self.value, self.label.as_ptr(),
self.min, self.value,
self.max, self.min,
self.display_format.as_ptr()) self.max,
self.display_format.as_ptr(),
)
} }
} }
} }
@ -123,12 +125,14 @@ impl<'ui, 'p> SliderFloat<'ui, 'p> {
} }
pub fn build(self) -> bool { pub fn build(self) -> bool {
unsafe { unsafe {
imgui_sys::igSliderFloat(self.label.as_ptr(), imgui_sys::igSliderFloat(
self.value, self.label.as_ptr(),
self.min, self.value,
self.max, self.min,
self.display_format.as_ptr(), self.max,
self.power) self.display_format.as_ptr(),
self.power,
)
} }
} }
} }

View File

@ -1,5 +1,5 @@
use std::borrow::Borrow; use std::borrow::Borrow;
use std::ffi::{CStr}; use std::ffi::CStr;
use std::fmt; use std::fmt;
use std::mem; use std::mem;
use std::ops::Deref; use std::ops::Deref;
@ -22,9 +22,7 @@ impl ImString {
v.push(b'\0'); v.push(b'\0');
ImString(v) ImString(v)
} }
pub unsafe fn from_utf8_with_nul_unchecked(v: Vec<u8>) -> ImString { pub unsafe fn from_utf8_with_nul_unchecked(v: Vec<u8>) -> ImString { ImString(v) }
ImString(v)
}
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.0.clear(); self.0.clear();
self.0.push(b'\0'); self.0.push(b'\0');
@ -40,12 +38,8 @@ impl ImString {
} }
pub fn capacity(&self) -> usize { self.0.capacity() - 1 } pub fn capacity(&self) -> usize { self.0.capacity() - 1 }
pub fn capacity_with_nul(&self) -> usize { self.0.capacity() } pub fn capacity_with_nul(&self) -> usize { self.0.capacity() }
pub fn reserve(&mut self, additional: usize) { pub fn reserve(&mut self, additional: usize) { self.0.reserve(additional); }
self.0.reserve(additional); pub fn reserve_exact(&mut self, additional: usize) { self.0.reserve_exact(additional); }
}
pub fn reserve_exact(&mut self, additional: usize) {
self.0.reserve_exact(additional);
}
pub fn as_ptr(&self) -> *const c_char { self.0.as_ptr() as *const _ } pub fn as_ptr(&self) -> *const c_char { self.0.as_ptr() as *const _ }
pub fn as_mut_ptr(&mut self) -> *mut c_char { self.0.as_mut_ptr() as *mut _ } pub fn as_mut_ptr(&mut self) -> *mut c_char { self.0.as_mut_ptr() as *mut _ }
@ -101,19 +95,13 @@ impl<'a> Default for &'a ImStr {
} }
impl fmt::Debug for ImStr { impl fmt::Debug for ImStr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&self.0, f) }
fmt::Debug::fmt(&self.0, f)
}
} }
impl ImStr { impl ImStr {
pub unsafe fn from_utf8_with_nul_unchecked(bytes: &[u8]) -> &ImStr { pub unsafe fn from_utf8_with_nul_unchecked(bytes: &[u8]) -> &ImStr { mem::transmute(bytes) }
mem::transmute(bytes)
}
pub fn as_ptr(&self) -> *const c_char { self.0.as_ptr() } pub fn as_ptr(&self) -> *const c_char { self.0.as_ptr() }
pub fn to_str(&self) -> &str { pub fn to_str(&self) -> &str { unsafe { str::from_utf8_unchecked(self.0.to_bytes()) } }
unsafe { str::from_utf8_unchecked(self.0.to_bytes()) }
}
} }
impl<'a> Into<&'a CStr> for &'a ImStr { impl<'a> Into<&'a CStr> for &'a ImStr {
@ -135,7 +123,5 @@ impl ToOwned for ImStr {
impl Deref for ImStr { impl Deref for ImStr {
type Target = str; type Target = str;
fn deref(&self) -> &str { fn deref(&self) -> &str { unsafe { str::from_utf8_unchecked(self.0.to_bytes()) } }
unsafe { str::from_utf8_unchecked(self.0.to_bytes()) }
}
} }

View File

@ -38,9 +38,11 @@ impl<'ui, 'p> TreeNode<'ui, 'p> {
if !self.opened_cond.is_empty() { if !self.opened_cond.is_empty() {
imgui_sys::igSetNextTreeNodeOpen(self.opened, self.opened_cond); imgui_sys::igSetNextTreeNodeOpen(self.opened, self.opened_cond);
} }
imgui_sys::igTreeNodeStr(self.id.as_ptr(), imgui_sys::igTreeNodeStr(
super::fmt_ptr(), self.id.as_ptr(),
self.label.unwrap_or(self.id).as_ptr()) super::fmt_ptr(),
self.label.unwrap_or(self.id).as_ptr(),
)
}; };
if render { if render {
f(); f();
@ -83,8 +85,7 @@ impl<'ui, 'p> CollapsingHeader<'ui, 'p> {
} }
#[inline] #[inline]
pub fn open_on_double_click(mut self, value: bool) -> Self { pub fn open_on_double_click(mut self, value: bool) -> Self {
self.flags self.flags.set(ImGuiTreeNodeFlags::OpenOnDoubleClick, value);
.set(ImGuiTreeNodeFlags::OpenOnDoubleClick, value);
self self
} }
#[inline] #[inline]

View File

@ -80,8 +80,7 @@ impl<'ui, 'p> Window<'ui, 'p> {
} }
#[inline] #[inline]
pub fn scrollable(mut self, value: bool) -> Self { pub fn scrollable(mut self, value: bool) -> Self {
self.flags self.flags.set(ImGuiWindowFlags::NoScrollWithMouse, !value);
.set(ImGuiWindowFlags::NoScrollWithMouse, !value);
self self
} }
#[inline] #[inline]
@ -116,38 +115,44 @@ impl<'ui, 'p> Window<'ui, 'p> {
} }
#[inline] #[inline]
pub fn horizontal_scrollbar(mut self, value: bool) -> Self { pub fn horizontal_scrollbar(mut self, value: bool) -> Self {
self.flags self.flags.set(ImGuiWindowFlags::HorizontalScrollbar, value);
.set(ImGuiWindowFlags::HorizontalScrollbar, value);
self self
} }
#[inline] #[inline]
pub fn no_focus_on_appearing(mut self, value: bool) -> Self { pub fn no_focus_on_appearing(mut self, value: bool) -> Self {
self.flags self.flags.set(ImGuiWindowFlags::NoFocusOnAppearing, value);
.set(ImGuiWindowFlags::NoFocusOnAppearing, value);
self self
} }
#[inline] #[inline]
pub fn no_bring_to_front_on_focus(mut self, value: bool) -> Self { pub fn no_bring_to_front_on_focus(mut self, value: bool) -> Self {
self.flags self.flags.set(
.set(ImGuiWindowFlags::NoBringToFrontOnFocus, value); ImGuiWindowFlags::NoBringToFrontOnFocus,
value,
);
self self
} }
#[inline] #[inline]
pub fn always_vertical_scrollbar(mut self, value: bool) -> Self { pub fn always_vertical_scrollbar(mut self, value: bool) -> Self {
self.flags self.flags.set(
.set(ImGuiWindowFlags::AlwaysVerticalScrollbar, value); ImGuiWindowFlags::AlwaysVerticalScrollbar,
value,
);
self self
} }
#[inline] #[inline]
pub fn always_horizontal_scrollbar(mut self, value: bool) -> Self { pub fn always_horizontal_scrollbar(mut self, value: bool) -> Self {
self.flags self.flags.set(
.set(ImGuiWindowFlags::AlwaysHorizontalScrollbar, value); ImGuiWindowFlags::AlwaysHorizontalScrollbar,
value,
);
self self
} }
#[inline] #[inline]
pub fn always_use_window_padding(mut self, value: bool) -> Self { pub fn always_use_window_padding(mut self, value: bool) -> Self {
self.flags self.flags.set(
.set(ImGuiWindowFlags::AlwaysUseWindowPadding, value); ImGuiWindowFlags::AlwaysUseWindowPadding,
value,
);
self self
} }
pub fn build<F: FnOnce()>(self, f: F) { pub fn build<F: FnOnce()>(self, f: F) {
@ -158,13 +163,15 @@ impl<'ui, 'p> Window<'ui, 'p> {
if !self.size_cond.is_empty() { if !self.size_cond.is_empty() {
imgui_sys::igSetNextWindowSize(self.size.into(), self.size_cond); imgui_sys::igSetNextWindowSize(self.size.into(), self.size_cond);
} }
imgui_sys::igBegin2(self.name.as_ptr(), imgui_sys::igBegin2(
self.opened self.name.as_ptr(),
.map(|x| x as *mut bool) self.opened.map(|x| x as *mut bool).unwrap_or(
.unwrap_or(ptr::null_mut()), ptr::null_mut(),
ImVec2::new(0.0, 0.0), ),
self.bg_alpha, ImVec2::new(0.0, 0.0),
self.flags) self.bg_alpha,
self.flags,
)
}; };
if render { if render {
f(); f();