mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
Pull parameter stack updates from 0.1-dev
This commit is contained in:
parent
b0e37f7a22
commit
965dd40876
@ -284,7 +284,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
window = window.opened(opened)
|
||||
}
|
||||
window.build(|| {
|
||||
ui.push_item_width(-140.0);
|
||||
let _token = ui.push_item_width(-140.0);
|
||||
ui.text(format!("dear imgui says hello. ({})", imgui::dear_imgui_version()));
|
||||
ui.menu_bar(|| {
|
||||
ui.menu(im_str!("Menu")).build(|| {
|
||||
@ -651,17 +651,16 @@ CTRL+click on individual component to input value.\n",
|
||||
ui.popup_modal(im_str!("Delete?")).always_auto_resize(true).build(|| {
|
||||
ui.text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
|
||||
ui.separator();
|
||||
ui.with_style_var(StyleVar::FramePadding([0.0, 0.0]), || {
|
||||
ui.checkbox(im_str!("Don't ask me next time"), &mut state.dont_ask_me_next_time);
|
||||
let _token = ui.push_style_var(StyleVar::FramePadding([0.0, 0.0]));
|
||||
ui.checkbox(im_str!("Don't ask me next time"), &mut state.dont_ask_me_next_time);
|
||||
|
||||
if ui.button(im_str!("OK"), [120.0, 0.0]) {
|
||||
ui.close_current_popup();
|
||||
}
|
||||
ui.same_line(0.0);
|
||||
if ui.button(im_str!("Cancel"), [120.0, 0.0]) {
|
||||
ui.close_current_popup();
|
||||
}
|
||||
});
|
||||
if ui.button(im_str!("OK"), [120.0, 0.0]) {
|
||||
ui.close_current_popup();
|
||||
}
|
||||
ui.same_line(0.0);
|
||||
if ui.button(im_str!("Cancel"), [120.0, 0.0]) {
|
||||
ui.close_current_popup();
|
||||
}
|
||||
});
|
||||
|
||||
if ui.button(im_str!("Stacked modals.."), [0.0, 0.0]) {
|
||||
@ -802,7 +801,7 @@ output your content because that would create a feedback loop.",
|
||||
fn show_example_app_fixed_overlay(ui: &Ui, opened: &mut bool) {
|
||||
const DISTANCE: f32 = 10.0;
|
||||
let window_pos = [DISTANCE, DISTANCE];
|
||||
ui.with_color_var(StyleColor::WindowBg, [0.0, 0.0, 0.0, 0.3], || {
|
||||
let _token = ui.push_style_color(StyleColor::WindowBg, [0.0, 0.0, 0.0, 0.3]);
|
||||
ui.window(im_str!("Example: Fixed Overlay"))
|
||||
.opened(opened)
|
||||
.position(window_pos, Condition::Always)
|
||||
@ -820,7 +819,6 @@ fn show_example_app_fixed_overlay(ui: &Ui, opened: &mut bool) {
|
||||
mouse_pos[0], mouse_pos[1]
|
||||
));
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn show_example_app_manipulating_window_title(ui: &Ui) {
|
||||
|
||||
@ -7,6 +7,7 @@ use std::str;
|
||||
use crate::input::keyboard::Key;
|
||||
use crate::input::mouse::MouseButton;
|
||||
use crate::internal::RawCast;
|
||||
use crate::style::{StyleColor, StyleVar};
|
||||
use crate::{Context, Ui};
|
||||
|
||||
bitflags!(
|
||||
@ -666,3 +667,56 @@ pub fn get_version() -> &'static str {
|
||||
str::from_utf8_unchecked(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ui> Ui<'ui> {
|
||||
#[deprecated(since = "0.1.0", note = "use Ui::push_style_color instead")]
|
||||
pub fn with_color_var<T, F>(&self, style_color: StyleColor, color: [f32; 4], f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let _token = self.push_style_color(style_color, color);
|
||||
f()
|
||||
}
|
||||
#[deprecated(since = "0.1.0", note = "use Ui::push_style_colors instead")]
|
||||
pub fn with_color_vars<'a, T, F, I>(&self, style_colors: I, f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
I: IntoIterator<Item = &'a (StyleColor, [f32; 4])>,
|
||||
{
|
||||
let _token = self.push_style_colors(style_colors);
|
||||
f()
|
||||
}
|
||||
#[deprecated(since = "0.1.0", note = "use Ui::push_style_var instead")]
|
||||
pub fn with_style_var<T, F>(&self, style_var: StyleVar, f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let _token = self.push_style_var(style_var);
|
||||
f()
|
||||
}
|
||||
#[deprecated(since = "0.1.0", note = "use Ui::push_style_vars instead")]
|
||||
pub fn with_style_vars<'a, T, F, I>(&self, style_vars: I, f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
I: IntoIterator<Item = &'a StyleVar>,
|
||||
{
|
||||
let _token = self.push_style_vars(style_vars);
|
||||
f()
|
||||
}
|
||||
#[deprecated(since = "0.1.0", note = "use Ui::push_item_width instead")]
|
||||
pub fn with_item_width<T, F>(&self, item_width: f32, f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let _token = self.push_item_width(item_width);
|
||||
f()
|
||||
}
|
||||
#[deprecated(since = "0.1.0", note = "use Ui::push_text_wrap_pos instead")]
|
||||
pub fn with_text_wrap_pos<T, F>(&self, wrap_pos_x: f32, f: F) -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let _token = self.push_text_wrap_pos(wrap_pos_x);
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
262
src/lib.rs
262
src/lib.rs
@ -43,7 +43,8 @@ pub use self::sliders::{
|
||||
SliderFloat, SliderFloat2, SliderFloat3, SliderFloat4, SliderInt, SliderInt2, SliderInt3,
|
||||
SliderInt4,
|
||||
};
|
||||
pub use self::string::{ImStr, ImString};
|
||||
pub use self::stacks::*;
|
||||
pub use self::string::*;
|
||||
pub use self::style::*;
|
||||
pub use self::trees::{CollapsingHeader, TreeNode};
|
||||
pub use self::window::Window;
|
||||
@ -68,11 +69,13 @@ mod popup_modal;
|
||||
mod progressbar;
|
||||
mod render;
|
||||
mod sliders;
|
||||
mod stacks;
|
||||
mod string;
|
||||
mod style;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
mod trees;
|
||||
mod widget;
|
||||
mod window;
|
||||
mod window_draw_list;
|
||||
|
||||
@ -122,6 +125,12 @@ impl<'ui> Ui<'ui> {
|
||||
},
|
||||
}
|
||||
}
|
||||
pub fn clone_style(&self) -> Style {
|
||||
*self.ctx.style()
|
||||
}
|
||||
pub fn style_color(&self, style_color: StyleColor) -> [f32; 4] {
|
||||
self.ctx.style()[style_color]
|
||||
}
|
||||
pub fn get_time(&self) -> f64 {
|
||||
unsafe { sys::igGetTime() }
|
||||
}
|
||||
@ -201,29 +210,6 @@ impl<'ui> Ui<'ui> {
|
||||
|
||||
// Layout
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Pushes a value to the item width stack.
|
||||
pub fn push_item_width(&self, width: f32) {
|
||||
unsafe { sys::igPushItemWidth(width) }
|
||||
}
|
||||
|
||||
/// Pops a value from the item width stack.
|
||||
///
|
||||
/// # Aborts
|
||||
/// The current process is aborted if the item width stack is empty.
|
||||
pub fn pop_item_width(&self) {
|
||||
unsafe { sys::igPopItemWidth() }
|
||||
}
|
||||
|
||||
/// Runs a function after temporarily pushing a value to the item width stack.
|
||||
pub fn with_item_width<F>(&self, width: f32, f: F)
|
||||
where
|
||||
F: FnOnce(),
|
||||
{
|
||||
self.push_item_width(width);
|
||||
f();
|
||||
self.pop_item_width();
|
||||
}
|
||||
|
||||
pub fn separator(&self) {
|
||||
unsafe { sys::igSeparator() };
|
||||
}
|
||||
@ -390,57 +376,11 @@ impl<'ui> Ui<'ui> {
|
||||
|
||||
// Widgets
|
||||
impl<'ui> Ui<'ui> {
|
||||
pub fn text<T: AsRef<str>>(&self, text: T) {
|
||||
let s = text.as_ref();
|
||||
unsafe {
|
||||
let start = s.as_ptr();
|
||||
let end = start.add(s.len());
|
||||
sys::igTextUnformatted(start as *const c_char, end as *const c_char);
|
||||
}
|
||||
}
|
||||
pub fn text_colored<'p>(&self, col: [f32; 4], text: &'p ImStr) {
|
||||
unsafe {
|
||||
sys::igTextColored(col.into(), fmt_ptr(), text.as_ptr());
|
||||
}
|
||||
}
|
||||
pub fn text_disabled<'p>(&self, text: &'p ImStr) {
|
||||
unsafe {
|
||||
sys::igTextDisabled(fmt_ptr(), text.as_ptr());
|
||||
}
|
||||
}
|
||||
pub fn text_wrapped<'p>(&self, text: &'p ImStr) {
|
||||
unsafe {
|
||||
sys::igTextWrapped(fmt_ptr(), text.as_ptr());
|
||||
}
|
||||
}
|
||||
/// Set word-wrapping for `text_*()` commands.
|
||||
/// - `< 0.0`: no wrapping;
|
||||
/// - `= 0.0`: wrap to end of window (or column);
|
||||
/// - `> 0.0`: wrap at `wrap_pos_x` position in window local space
|
||||
pub fn with_text_wrap_pos<F: FnOnce()>(&self, wrap_pos_x: f32, f: F) {
|
||||
unsafe {
|
||||
sys::igPushTextWrapPos(wrap_pos_x);
|
||||
}
|
||||
f();
|
||||
unsafe {
|
||||
sys::igPopTextWrapPos();
|
||||
}
|
||||
}
|
||||
pub fn label_text<'p>(&self, label: &'p ImStr, text: &'p ImStr) {
|
||||
unsafe {
|
||||
sys::igLabelText(label.as_ptr(), fmt_ptr(), text.as_ptr());
|
||||
}
|
||||
}
|
||||
pub fn bullet(&self) {
|
||||
unsafe {
|
||||
sys::igBullet();
|
||||
}
|
||||
}
|
||||
pub fn bullet_text<'p>(&self, text: &'p ImStr) {
|
||||
unsafe {
|
||||
sys::igBulletText(fmt_ptr(), text.as_ptr());
|
||||
}
|
||||
}
|
||||
pub fn button(&self, label: &ImStr, size: [f32; 2]) -> bool {
|
||||
unsafe { sys::igButton(label.as_ptr(), size.into()) }
|
||||
}
|
||||
@ -1017,188 +957,6 @@ impl<'ui> Ui<'ui> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Runs a function after temporarily pushing a value to the style stack.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust,no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut imgui = Context::create();
|
||||
/// # let ui = imgui.frame();
|
||||
/// ui.with_style_var(StyleVar::Alpha(0.2), || {
|
||||
/// ui.text(im_str!("AB"));
|
||||
/// });
|
||||
/// ```
|
||||
pub fn with_style_var<F: FnOnce()>(&self, style_var: StyleVar, f: F) {
|
||||
self.push_style_var(style_var);
|
||||
f();
|
||||
unsafe { sys::igPopStyleVar(1) }
|
||||
}
|
||||
|
||||
/// Runs a function after temporarily pushing an array of values into the stack. Supporting
|
||||
/// multiple is also easy since you can freely mix and match them in a safe manner.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust,no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut imgui = Context::create();
|
||||
/// # let ui = imgui.frame();
|
||||
/// # let styles = [StyleVar::Alpha(0.2), StyleVar::WindowPadding([1.0, 1.0])];
|
||||
/// ui.with_style_vars(&styles, || {
|
||||
/// ui.text(im_str!("A"));
|
||||
/// ui.text(im_str!("B"));
|
||||
/// ui.text(im_str!("C"));
|
||||
/// ui.text(im_str!("D"));
|
||||
/// });
|
||||
/// ```
|
||||
pub fn with_style_vars<F: FnOnce()>(&self, style_vars: &[StyleVar], f: F) {
|
||||
for &style_var in style_vars {
|
||||
self.push_style_var(style_var);
|
||||
}
|
||||
f();
|
||||
unsafe { sys::igPopStyleVar(style_vars.len() as i32) };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn push_style_var(&self, style_var: StyleVar) {
|
||||
use crate::style::StyleVar::*;
|
||||
use crate::sys::{igPushStyleVarFloat, igPushStyleVarVec2};
|
||||
match style_var {
|
||||
Alpha(v) => unsafe { igPushStyleVarFloat(sys::ImGuiStyleVar_Alpha as i32, v) },
|
||||
WindowPadding(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_WindowPadding as i32, v.into())
|
||||
},
|
||||
WindowRounding(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_WindowRounding as i32, v)
|
||||
},
|
||||
WindowBorderSize(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_WindowBorderSize as i32, v)
|
||||
},
|
||||
WindowMinSize(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_WindowMinSize as i32, v.into())
|
||||
},
|
||||
WindowTitleAlign(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_WindowTitleAlign as i32, v.into())
|
||||
},
|
||||
ChildRounding(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_ChildRounding as i32, v)
|
||||
},
|
||||
ChildBorderSize(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_ChildBorderSize as i32, v)
|
||||
},
|
||||
PopupRounding(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_PopupRounding as i32, v)
|
||||
},
|
||||
PopupBorderSize(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_PopupBorderSize as i32, v)
|
||||
},
|
||||
FramePadding(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_FramePadding as i32, v.into())
|
||||
},
|
||||
FrameRounding(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_FrameRounding as i32, v)
|
||||
},
|
||||
FrameBorderSize(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_FrameBorderSize as i32, v)
|
||||
},
|
||||
ItemSpacing(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_ItemSpacing as i32, v.into())
|
||||
},
|
||||
ItemInnerSpacing(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_ItemInnerSpacing as i32, v.into())
|
||||
},
|
||||
IndentSpacing(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_IndentSpacing as i32, v)
|
||||
},
|
||||
ScrollbarSize(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_ScrollbarSize as i32, v)
|
||||
},
|
||||
ScrollbarRounding(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_ScrollbarRounding as i32, v)
|
||||
},
|
||||
GrabMinSize(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_GrabMinSize as i32, v)
|
||||
},
|
||||
GrabRounding(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_GrabRounding as i32, v)
|
||||
},
|
||||
TabRounding(v) => unsafe {
|
||||
igPushStyleVarFloat(sys::ImGuiStyleVar_TabRounding as i32, v)
|
||||
},
|
||||
ButtonTextAlign(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_ButtonTextAlign as i32, v.into())
|
||||
},
|
||||
SelectableTextAlign(v) => unsafe {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_SelectableTextAlign as i32, v.into())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Runs a function after temporarily pushing a value to the color stack.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust,no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut imgui = Context::create();
|
||||
/// # let ui = imgui.frame();
|
||||
/// ui.with_color_var(StyleColor::Text, [1.0, 0.0, 0.0, 1.0], || {
|
||||
/// ui.text_wrapped(im_str!("AB"));
|
||||
/// });
|
||||
/// ```
|
||||
pub fn with_color_var<F: FnOnce()>(&self, var: StyleColor, color: [f32; 4], f: F) {
|
||||
unsafe {
|
||||
sys::igPushStyleColor(var as _, color.into());
|
||||
}
|
||||
f();
|
||||
unsafe {
|
||||
sys::igPopStyleColor(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs a function after temporarily pushing an array of values to the color stack.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust,no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut imgui = Context::create();
|
||||
/// # let ui = imgui.frame();
|
||||
/// let red = [1.0, 0.0, 0.0, 1.0];
|
||||
/// let green = [0.0, 1.0, 0.0, 1.0];
|
||||
/// # let vars = [(StyleColor::Text, red), (StyleColor::TextDisabled, green)];
|
||||
/// ui.with_color_vars(&vars, || {
|
||||
/// ui.text_wrapped(im_str!("AB"));
|
||||
/// });
|
||||
/// ```
|
||||
pub fn with_color_vars<F: FnOnce()>(&self, color_vars: &[(StyleColor, [f32; 4])], f: F) {
|
||||
for &(color_var, color) in color_vars {
|
||||
unsafe {
|
||||
sys::igPushStyleColor(color_var as _, color.into());
|
||||
}
|
||||
}
|
||||
f();
|
||||
unsafe { sys::igPopStyleColor(color_vars.len() as i32) };
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Runs a function after temporarily pushing an array of values to the
|
||||
/// style and color stack.
|
||||
pub fn with_style_and_color_vars<F>(
|
||||
&self,
|
||||
style_vars: &[StyleVar],
|
||||
color_vars: &[(StyleColor, [f32; 4])],
|
||||
f: F,
|
||||
) where
|
||||
F: FnOnce(),
|
||||
{
|
||||
self.with_style_vars(style_vars, || {
|
||||
self.with_color_vars(color_vars, f);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// # Utilities
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Returns `true` if the last item is being hovered by the mouse.
|
||||
|
||||
303
src/stacks.rs
Normal file
303
src/stacks.rs
Normal file
@ -0,0 +1,303 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
||||
use crate::fonts::atlas::FontId;
|
||||
use crate::internal::RawCast;
|
||||
use crate::style::{StyleColor, StyleVar};
|
||||
use crate::sys;
|
||||
use crate::Ui;
|
||||
|
||||
/// # Parameter stacks (shared)
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Switches to the given font by pushing it to the font stack.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the font atlas does not contain the given font
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut ctx = Context::create();
|
||||
/// # let font_data_sources = [];
|
||||
/// // At initialization time
|
||||
/// let my_custom_font = ctx.fonts().add_font(&font_data_sources);
|
||||
/// # let ui = ctx.frame();
|
||||
/// // During UI construction
|
||||
/// let _token = ui.push_font(my_custom_font);
|
||||
/// ui.text("I use the custom font!");
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn push_font(&self, id: FontId) -> FontStackToken {
|
||||
let fonts = self.fonts();
|
||||
let font = fonts
|
||||
.get_font(id)
|
||||
.expect("Font atlas did not contain the given font");
|
||||
unsafe { sys::igPushFont(font.raw() as *const _ as *mut _) };
|
||||
FontStackToken { _ui: PhantomData }
|
||||
}
|
||||
/// Changes a style color by pushing a change to the color stack.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut ctx = Context::create();
|
||||
/// # let ui = ctx.frame();
|
||||
/// const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
|
||||
/// let _token = ui.push_style_color(StyleColor::Text, RED);
|
||||
/// ui.text("I'm red!");
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn push_style_color(&self, style_color: StyleColor, color: [f32; 4]) -> ColorStackToken {
|
||||
unsafe { sys::igPushStyleColor(style_color as i32, color.into()) };
|
||||
ColorStackToken {
|
||||
count: 1,
|
||||
_ui: PhantomData,
|
||||
}
|
||||
}
|
||||
/// Changes style colors by pushing several changes to the color stack.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut ctx = Context::create();
|
||||
/// # let ui = ctx.frame();
|
||||
/// const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
|
||||
/// const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
|
||||
/// let _token = ui.push_style_colors(&[
|
||||
/// (StyleColor::Text, RED),
|
||||
/// (StyleColor::TextDisabled, GREEN),
|
||||
/// ]);
|
||||
/// ui.text("I'm red!");
|
||||
/// ui.text_disabled("I'm green!");
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn push_style_colors<'a, I>(&self, style_colors: I) -> ColorStackToken
|
||||
where
|
||||
I: IntoIterator<Item = &'a (StyleColor, [f32; 4])>,
|
||||
{
|
||||
let mut count = 0;
|
||||
for &(style_color, color) in style_colors {
|
||||
unsafe { sys::igPushStyleColor(style_color as i32, color.into()) };
|
||||
count += 1;
|
||||
}
|
||||
ColorStackToken {
|
||||
count,
|
||||
_ui: PhantomData,
|
||||
}
|
||||
}
|
||||
/// Changes a style variable by pushing a change to the style stack.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut ctx = Context::create();
|
||||
/// # let ui = ctx.frame();
|
||||
/// let _token = ui.push_style_var(StyleVar::Alpha(0.2));
|
||||
/// ui.text("I'm transparent!");
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn push_style_var(&self, style_var: StyleVar) -> StyleStackToken {
|
||||
unsafe { push_style_var(style_var) };
|
||||
StyleStackToken {
|
||||
count: 1,
|
||||
_ui: PhantomData,
|
||||
}
|
||||
}
|
||||
/// Changes style variables by pushing several changes to the style stack.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use imgui::*;
|
||||
/// # let mut ctx = Context::create();
|
||||
/// # let ui = ctx.frame();
|
||||
/// let _token = ui.push_style_vars(&[
|
||||
/// StyleVar::Alpha(0.2),
|
||||
/// StyleVar::ItemSpacing([50.0, 50.0])
|
||||
/// ]);
|
||||
/// ui.text("We're transparent...");
|
||||
/// ui.text("...with large spacing as well");
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn push_style_vars<'a, I>(&self, style_vars: I) -> StyleStackToken
|
||||
where
|
||||
I: IntoIterator<Item = &'a StyleVar>,
|
||||
{
|
||||
let mut count = 0;
|
||||
for &style_var in style_vars {
|
||||
unsafe { push_style_var(style_var) };
|
||||
count += 1;
|
||||
}
|
||||
StyleStackToken {
|
||||
count,
|
||||
_ui: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a change pushed to the font stack
|
||||
pub struct FontStackToken<'ui> {
|
||||
_ui: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
impl<'ui> Drop for FontStackToken<'ui> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::igPopFont() };
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents one or more changes pushed to the color stack
|
||||
pub struct ColorStackToken<'ui> {
|
||||
count: usize,
|
||||
_ui: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
impl<'ui> Drop for ColorStackToken<'ui> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::igPopStyleColor(self.count as i32) };
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents one or more changes pushed to the style stack
|
||||
pub struct StyleStackToken<'ui> {
|
||||
count: usize,
|
||||
_ui: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
impl<'ui> Drop for StyleStackToken<'ui> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::igPopStyleVar(self.count as i32) };
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn push_style_var(style_var: StyleVar) {
|
||||
use crate::style::StyleVar::*;
|
||||
use crate::sys::{igPushStyleVarFloat, igPushStyleVarVec2};
|
||||
match style_var {
|
||||
Alpha(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_Alpha as i32, v),
|
||||
WindowPadding(v) => igPushStyleVarVec2(sys::ImGuiStyleVar_WindowPadding as i32, v.into()),
|
||||
WindowRounding(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_WindowRounding as i32, v),
|
||||
WindowBorderSize(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_WindowBorderSize as i32, v),
|
||||
WindowMinSize(v) => igPushStyleVarVec2(sys::ImGuiStyleVar_WindowMinSize as i32, v.into()),
|
||||
WindowTitleAlign(v) => {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_WindowTitleAlign as i32, v.into())
|
||||
}
|
||||
ChildRounding(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_ChildRounding as i32, v),
|
||||
ChildBorderSize(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_ChildBorderSize as i32, v),
|
||||
PopupRounding(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_PopupRounding as i32, v),
|
||||
PopupBorderSize(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_PopupBorderSize as i32, v),
|
||||
FramePadding(v) => igPushStyleVarVec2(sys::ImGuiStyleVar_FramePadding as i32, v.into()),
|
||||
FrameRounding(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_FrameRounding as i32, v),
|
||||
FrameBorderSize(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_FrameBorderSize as i32, v),
|
||||
ItemSpacing(v) => igPushStyleVarVec2(sys::ImGuiStyleVar_ItemSpacing as i32, v.into()),
|
||||
ItemInnerSpacing(v) => {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_ItemInnerSpacing as i32, v.into())
|
||||
}
|
||||
IndentSpacing(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_IndentSpacing as i32, v),
|
||||
ScrollbarSize(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_ScrollbarSize as i32, v),
|
||||
ScrollbarRounding(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_ScrollbarRounding as i32, v),
|
||||
GrabMinSize(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_GrabMinSize as i32, v),
|
||||
GrabRounding(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_GrabRounding as i32, v),
|
||||
TabRounding(v) => igPushStyleVarFloat(sys::ImGuiStyleVar_TabRounding as i32, v),
|
||||
ButtonTextAlign(v) => {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_ButtonTextAlign as i32, v.into())
|
||||
}
|
||||
SelectableTextAlign(v) => {
|
||||
igPushStyleVarVec2(sys::ImGuiStyleVar_SelectableTextAlign as i32, v.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # Parameter stacks (current window)
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Changes the item width by pushing a change to the item width stack.
|
||||
///
|
||||
/// - `> 0.0`: width is `item_width` pixels
|
||||
/// - `= 0.0`: default to ~2/3 of window width
|
||||
/// - `< 0.0`: `item_width` pixels relative to the right of window (-1.0 always aligns width to
|
||||
/// the right side)
|
||||
#[must_use]
|
||||
pub fn push_item_width(&self, item_width: f32) -> ItemWidthStackToken {
|
||||
unsafe { sys::igPushItemWidth(item_width) };
|
||||
ItemWidthStackToken { _ui: PhantomData }
|
||||
}
|
||||
/// Changes the text wrapping position by pushing a change to the text wrapping position stack.
|
||||
///
|
||||
/// - `> 0.0`: wrap at `wrap_pos_x` position in window local space
|
||||
/// - `= 0.0`: wrap to end of window ( or column)
|
||||
/// - `< 0.0`: no wrapping
|
||||
#[must_use]
|
||||
pub fn push_text_wrap_pos(&self, wrap_pos_x: f32) -> TextWrapPosStackToken {
|
||||
unsafe { sys::igPushTextWrapPos(wrap_pos_x) };
|
||||
TextWrapPosStackToken { _ui: PhantomData }
|
||||
}
|
||||
/// Changes an item flag by pushing a change to the item flag stack
|
||||
#[must_use]
|
||||
pub fn push_item_flag(&self, item_flag: ItemFlag) -> ItemFlagsStackToken {
|
||||
use self::ItemFlag::*;
|
||||
match item_flag {
|
||||
AllowKeyboardFocus(v) => unsafe { sys::igPushAllowKeyboardFocus(v) },
|
||||
ButtonRepeat(v) => unsafe { sys::igPushButtonRepeat(v) },
|
||||
}
|
||||
ItemFlagsStackToken {
|
||||
discriminant: mem::discriminant(&item_flag),
|
||||
_ui: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A temporary change in item flags
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum ItemFlag {
|
||||
AllowKeyboardFocus(bool),
|
||||
ButtonRepeat(bool),
|
||||
}
|
||||
|
||||
/// Represents a change pushed to the item width stack
|
||||
pub struct ItemWidthStackToken<'ui> {
|
||||
_ui: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
impl<'ui> Drop for ItemWidthStackToken<'ui> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::igPopItemWidth() };
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a change pushed to the text wrap position stack
|
||||
pub struct TextWrapPosStackToken<'ui> {
|
||||
_ui: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
impl<'ui> Drop for TextWrapPosStackToken<'ui> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::igPopTextWrapPos() };
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a change pushed to the item flags stack
|
||||
pub struct ItemFlagsStackToken<'ui> {
|
||||
discriminant: mem::Discriminant<ItemFlag>,
|
||||
_ui: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
impl<'ui> Drop for ItemFlagsStackToken<'ui> {
|
||||
fn drop(&mut self) {
|
||||
const ALLOW_KEYBOARD_FOCUS: ItemFlag = ItemFlag::AllowKeyboardFocus(true);
|
||||
const BUTTON_REPEAT: ItemFlag = ItemFlag::ButtonRepeat(true);
|
||||
|
||||
if self.discriminant == mem::discriminant(&ALLOW_KEYBOARD_FOCUS) {
|
||||
unsafe { sys::igPopAllowKeyboardFocus() };
|
||||
} else if self.discriminant == mem::discriminant(&BUTTON_REPEAT) {
|
||||
unsafe { sys::igPopButtonRepeat() };
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
1
src/widget/mod.rs
Normal file
1
src/widget/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod text;
|
||||
44
src/widget/text.rs
Normal file
44
src/widget/text.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use crate::string::ImStr;
|
||||
use crate::style::StyleColor;
|
||||
use crate::Ui;
|
||||
|
||||
static FMT: &'static [u8] = b"%s\0";
|
||||
|
||||
#[inline]
|
||||
fn fmt_ptr() -> *const c_char {
|
||||
FMT.as_ptr() as *const c_char
|
||||
}
|
||||
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// Renders simple text
|
||||
pub fn text<T: AsRef<str>>(&self, text: T) {
|
||||
let s = text.as_ref();
|
||||
unsafe {
|
||||
let start = s.as_ptr();
|
||||
let end = start.add(s.len());
|
||||
sys::igTextUnformatted(start as *const c_char, end as *const c_char);
|
||||
}
|
||||
}
|
||||
/// Renders simple text using the given text color
|
||||
pub fn text_colored<T: AsRef<str>>(&self, color: [f32; 4], text: T) {
|
||||
let _ = self.push_style_color(StyleColor::Text, color);
|
||||
self.text(text);
|
||||
}
|
||||
/// Renders simple text using `StyleColor::TextDisabled` color
|
||||
pub fn text_disabled<T: AsRef<str>>(&self, text: T) {
|
||||
let color = self.style_color(StyleColor::TextDisabled);
|
||||
let _ = self.push_style_color(StyleColor::Text, color);
|
||||
self.text(text);
|
||||
}
|
||||
pub fn text_wrapped(&self, text: &ImStr) {
|
||||
unsafe { sys::igTextWrapped(fmt_ptr(), text.as_ptr()) }
|
||||
}
|
||||
pub fn label_text(&self, label: &ImStr, text: &ImStr) {
|
||||
unsafe { sys::igLabelText(label.as_ptr(), fmt_ptr(), text.as_ptr()) }
|
||||
}
|
||||
pub fn bullet_text(&self, text: &ImStr) {
|
||||
unsafe { sys::igBulletText(fmt_ptr(), text.as_ptr()) }
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user