Pull parameter stack updates from 0.1-dev

This commit is contained in:
Joonas Javanainen 2019-06-30 23:29:14 +03:00
parent b0e37f7a22
commit 965dd40876
No known key found for this signature in database
GPG Key ID: D39CCA5CB19B9179
6 changed files with 423 additions and 265 deletions

View File

@ -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) {

View File

@ -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()
}
}

View File

@ -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
View 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
View File

@ -0,0 +1 @@
pub mod text;

44
src/widget/text.rs Normal file
View 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()) }
}
}