Merge pull request #445 from dbr/drawimage

Add `DrawListMut::add_image` etc
This commit is contained in:
Jonathan Spira 2021-03-08 17:39:32 -08:00 committed by GitHub
commit 22eac761d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 560 additions and 145 deletions

View File

@ -5,7 +5,15 @@
- BREAKING: Created `with_x` variants for most functions which previously took multiple parameters where some had default arguments in the C++. This makes calling most functions simpler and more similar to the C++.
- The most likely breaking changes users will see is `button` and `same_line` now take one fewer parameter -- if you were calling `button` with `[0.0, 0.0]`, simply delete that -- otherwise, call `button_with_size`. Similarly, for `same_line`, if you were passing in `0.0.` simply delete that parameter. Otherwise, call `same_line_with_pos`.
- Removed legacy `ImGuiDragDropFlags` from `legacy.rs`, which were accidentally not cleared when they were remade in `drag_drop.rs` in v0.7.0.
- BREAKING: Removed `imgui::legacy` which contained the old style of flags. The remaining flags in `imgui::legacy` have been updated to be consistent with other flags in the project.
- `imgui::legacy::ImGuiDragDropFlags` were accidentally not cleared when they were remade in `drag_drop.rs` in v0.7.0.
- `imgui::legacy::ImGuiInputTextFlags` is now `imgui::input_widgets::InputTextFlags`
- `imgui::legacy::ImGuiTreeNodeFlags` is now `imgui::widget::tree::TreeNodeFlags`
- `imgui::legacy::ImDrawListFlags` is now `imgui::draw_list::DrawListFlags`
- `DrawListMut` has new methods to draw images
- The methods are `add_image`, `add_image_quad`, and `add_image_rounded`. The `imgui-examples/examples/custom_textures.rs` has been updated to show their usage.
- Additionally the `imgui::draw_list` module is now public, which contains the various draw list objects. While the `add_*` methods are preferred, `imgui::draw_list::Circle::new(&draw_list_mut, ...).build()` is equivalent
- BREAKING: Most tokens through the repository (eg. `WindowToken`, `TabBarToken`, `FontStackToken`, etc) now allow for permissive dropping -- i.e, you don't need to actually call the `.end()` method on them anymore. In exchange, these tokens have taken on a lifetime, which allows them to be safe. This could make some patterns impossible. Please file an issue if this causes a problem.
- `end()` no longer takes `Ui`. This is a breaking change, but hopefully should be trivial (and perhaps nice) for users to fix. Simply delete the argument, or add a `_` before the token's binding name and allow it to be dropped on its own.
@ -13,7 +21,7 @@
- BREAKING: `PopupModal`'s `new` was reworked so that it didn't take `Ui` until `build` was called. This is a breaking change if you were invoking it directly. Simply move your `ui` call to `build` or `begin`.
- Upgrade to [Dear ImGui v1.81](https://github.com/ocornut/imgui/releases/tag/v1.81)
- `imgui::ListBox::calculate_size(items_count: ..., height_in_items: ...)` has been removed as the function backing it has been marked as obsolete. The recommended approach is to calculate the size yourself and use `.size(...)` (or use the default auto-calculated size)
- BREAKING: `imgui::ListBox::calculate_size(items_count: ..., height_in_items: ...)` has been removed as the function backing it has been marked as obsolete. The recommended approach is to calculate the size yourself and use `.size(...)` (or use the default auto-calculated size)
## [0.7.0] - 2021-02-04

View File

@ -79,7 +79,7 @@ impl CustomTexturesApp {
fn show_textures(&self, ui: &Ui) {
Window::new(im_str!("Hello textures"))
.size([400.0, 600.0], Condition::FirstUseEver)
.size([400.0, 400.0], Condition::FirstUseEver)
.build(ui, || {
ui.text(im_str!("Hello textures!"));
if let Some(my_texture_id) = self.my_texture_id {
@ -91,6 +91,86 @@ impl CustomTexturesApp {
ui.text("Say hello to Lenna.jpg");
lenna.show(ui);
}
// Example of using custom textures on a button
if let Some(lenna) = &self.lenna {
ui.text("The Lenna buttons");
{
ui.invisible_button(im_str!("Boring Button"), [100.0, 100.0]);
// See also `imgui::Ui::style_color`
let tint_none = [1.0, 1.0, 1.0, 1.0];
let tint_green = [0.5, 1.0, 0.5, 1.0];
let tint_red = [1.0, 0.5, 0.5, 1.0];
let tint = match (
ui.is_item_hovered(),
ui.is_mouse_down(imgui::MouseButton::Left),
) {
(false, false) => tint_none,
(false, true) => tint_none,
(true, false) => tint_green,
(true, true) => tint_red,
};
let draw_list = ui.get_window_draw_list();
draw_list
.add_image(lenna.texture_id, ui.item_rect_min(), ui.item_rect_max())
.col(tint)
.build();
}
{
ui.same_line();
// Button using quad positioned image
ui.invisible_button(im_str!("Exciting Button"), [100.0, 100.0]);
// Button bounds
let min = ui.item_rect_min();
let max = ui.item_rect_max();
// get corner coordinates
let tl = [
min[0],
min[1] + (ui.frame_count() as f32 / 10.0).cos() * 10.0,
];
let tr = [
max[0],
min[1] + (ui.frame_count() as f32 / 10.0).sin() * 10.0,
];
let bl = [min[0], max[1]];
let br = max;
let draw_list = ui.get_window_draw_list();
draw_list
.add_image_quad(lenna.texture_id, tl, tr, br, bl)
.build();
}
// Rounded image
{
ui.same_line();
ui.invisible_button(im_str!("Smooth Button"), [100.0, 100.0]);
let draw_list = ui.get_window_draw_list();
draw_list
.add_image_rounded(
lenna.texture_id,
ui.item_rect_min(),
ui.item_rect_max(),
16.0,
)
// Tint brighter for visiblity of corners
.col([2.0, 0.5, 0.5, 1.0])
// Rounding on each corner can be changed separately
.round_top_left(ui.frame_count() / 60 % 4 == 0)
.round_top_right((ui.frame_count() + 1) / 60 % 4 == 1)
.round_bot_right((ui.frame_count() + 3) / 60 % 4 == 2)
.round_bot_left((ui.frame_count() + 2) / 60 % 4 == 3)
.build();
}
}
});
}
}

View File

@ -1,11 +1,64 @@
//! The draw list lets you create custom graphics within a window.
//!
//! Each dear imgui window contains its own draw list. You can use
//! [`Ui::get_window_draw_list`] to access the current window draw
//! list and draw custom primitives. You can interleave normal widget
//! calls and adding primitives to the current draw list.
//!
//! Interaction is mostly through the mtehods [`DrawListMut`] struct,
//! such as [`DrawListMut::add_line`], however you can also construct
//! structs like [`Line`] directly, then call
//! `Line::build` with a reference to your draw list
//!
//! There are examples such as `draw_list.rs` and `custom_textures.rs`
//! within the `imgui-examples` directory
use bitflags::bitflags;
use crate::ImColor32;
use sys::ImDrawList;
use super::Ui;
use crate::legacy::ImDrawCornerFlags;
use crate::render::renderer::TextureId;
use std::marker::PhantomData;
bitflags!(
/// Flags for indictating which corner of a rectangle should be rounded
#[repr(C)]
pub struct CornerFlags: u32 {
const NONE = sys::ImDrawCornerFlags_None;
const TOP_LEFT = sys::ImDrawCornerFlags_TopLeft;
const TOP_RIGHT = sys::ImDrawCornerFlags_TopRight;
const BOT_LEFT = sys::ImDrawCornerFlags_BotLeft;
const BOT_RIGHT = sys::ImDrawCornerFlags_BotRight;
const TOP = sys::ImDrawCornerFlags_Top;
const BOT = sys::ImDrawCornerFlags_Bot;
const LEFT = sys::ImDrawCornerFlags_Left;
const RIGHT = sys::ImDrawCornerFlags_Right;
const ALL = sys::ImDrawCornerFlags_All;
}
);
bitflags!(
/// Draw list flags
#[repr(C)]
pub struct DrawListFlags: u32 {
const NONE = sys::ImDrawListFlags_None;
/// Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines
/// thin enough to be drawn using textures, otherwise *3 the number of triangles)
const ANTI_ALIASED_LINES = sys::ImDrawListFlags_AntiAliasedLines;
/// Enable anti-aliased lines/borders using textures when possible. Require backend to render
/// with bilinear filtering.
const ANTI_ALIASED_LINES_USE_TEX = sys::ImDrawListFlags_AntiAliasedLinesUseTex;
/// Enable anti-aliased edge around filled shapes (rounded rectangles, circles).
const ANTI_ALIASED_FILL = sys::ImDrawListFlags_AntiAliasedFill;
/// Can emit 'VtxOffset > 0' to allow large meshes. Set when
/// [`BackendFlags::RENDERER_HAS_VTX_OFFSET`] is enabled.
const ALLOW_VTX_OFFSET = sys::ImDrawListFlags_AllowVtxOffset;
}
);
/// Object implementing the custom draw API.
///
/// Called from [`Ui::get_window_draw_list`], [`Ui::get_background_draw_list`] or [`Ui::get_foreground_draw_list`].
@ -265,6 +318,56 @@ impl<'ui> DrawListMut<'ui> {
}
}
/// # Images
impl<'ui> DrawListMut<'ui> {
/// Draw the specified image in the rect specified by `p_min` to
/// `p_max`.
///
/// # Examples
///
/// ```
/// # use imgui::*;
/// fn custom_button(ui: &Ui, img_id: TextureId) {
/// // Invisible button is good widget to customise with image
/// ui.invisible_button(im_str!("custom_button"), [100.0, 20.0]);
///
/// // Get draw list and draw image over invisible button
/// let draw_list = ui.get_window_draw_list();
/// draw_list
/// .add_image(img_id, ui.item_rect_min(), ui.item_rect_max())
/// .build();
/// }
/// ```
pub fn add_image(&'ui self, texture_id: TextureId, p_min: [f32; 2], p_max: [f32; 2]) -> Image {
Image::new(self, texture_id, p_min, p_max)
}
/// Draw the specified image to a quad with the specified
/// coordinates. Similar to [`DrawListMut::add_image`] but this
/// method is able to draw non-rectangle images.
pub fn add_image_quad(
&'ui self,
texture_id: TextureId,
p1: [f32; 2],
p2: [f32; 2],
p3: [f32; 2],
p4: [f32; 2],
) -> ImageQuad {
ImageQuad::new(self, texture_id, p1, p2, p3, p4)
}
/// Draw the speciied image, with rounded corners
pub fn add_image_rounded(
&'ui self,
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
rounding: f32,
) -> ImageRounded {
ImageRounded::new(self, texture_id, p_min, p_max, rounding)
}
}
/// Represents a line about to be drawn
#[must_use = "should call .build() to draw the object"]
pub struct Line<'ui> {
@ -316,7 +419,7 @@ pub struct Rect<'ui> {
p2: [f32; 2],
color: ImColor32,
rounding: f32,
flags: ImDrawCornerFlags,
flags: CornerFlags,
thickness: f32,
filled: bool,
draw_list: &'ui DrawListMut<'ui>,
@ -332,7 +435,7 @@ impl<'ui> Rect<'ui> {
p2,
color: c.into(),
rounding: 0.0,
flags: ImDrawCornerFlags::All,
flags: CornerFlags::ALL,
thickness: 1.0,
filled: false,
draw_list,
@ -348,25 +451,25 @@ impl<'ui> Rect<'ui> {
/// Set flag to indicate if rectangle's top-left corner will be rounded.
pub fn round_top_left(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::TopLeft, value);
self.flags.set(CornerFlags::TOP_LEFT, value);
self
}
/// Set flag to indicate if rectangle's top-right corner will be rounded.
pub fn round_top_right(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::TopRight, value);
self.flags.set(CornerFlags::TOP_RIGHT, value);
self
}
/// Set flag to indicate if rectangle's bottom-left corner will be rounded.
pub fn round_bot_left(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::BotLeft, value);
self.flags.set(CornerFlags::BOT_LEFT, value);
self
}
/// Set flag to indicate if rectangle's bottom-right corner will be rounded.
pub fn round_bot_right(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::BotRight, value);
self.flags.set(CornerFlags::BOT_RIGHT, value);
self
}
@ -392,7 +495,7 @@ impl<'ui> Rect<'ui> {
self.p2.into(),
self.color.into(),
self.rounding,
self.flags.bits(),
self.flags.bits() as i32,
);
}
} else {
@ -403,7 +506,7 @@ impl<'ui> Rect<'ui> {
self.p2.into(),
self.color.into(),
self.rounding,
self.flags.bits(),
self.flags.bits() as i32,
self.thickness,
);
}
@ -491,6 +594,7 @@ pub struct Circle<'ui> {
}
impl<'ui> Circle<'ui> {
/// Typically constructed by [`DrawListMut::add_circle`]
pub fn new<C>(draw_list: &'ui DrawListMut, center: [f32; 2], radius: f32, color: C) -> Self
where
C: Into<ImColor32>,
@ -567,7 +671,8 @@ pub struct BezierCurve<'ui> {
}
impl<'ui> BezierCurve<'ui> {
fn new<C>(
/// Typically constructed by [`DrawListMut::add_bezier_curve`]
pub fn new<C>(
draw_list: &'ui DrawListMut,
pos0: [f32; 2],
cp0: [f32; 2],
@ -619,3 +724,268 @@ impl<'ui> BezierCurve<'ui> {
}
}
}
/// Image draw list primitive, not to be confused with the widget
/// [`imgui::Image`](crate::Image).
#[must_use = "should call .build() to draw the object"]
pub struct Image<'ui> {
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
uv_min: [f32; 2],
uv_max: [f32; 2],
col: ImColor32,
draw_list: &'ui DrawListMut<'ui>,
}
impl<'ui> Image<'ui> {
/// Typically constructed by [`DrawListMut::add_image`]
pub fn new(
draw_list: &'ui DrawListMut,
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
) -> Self {
Self {
texture_id,
p_min,
p_max,
uv_min: [0.0, 0.0],
uv_max: [1.0, 1.0],
col: [1.0, 1.0, 1.0, 1.0].into(),
draw_list,
}
}
/// Set uv_min (default `[0.0, 0.0]`)
pub fn uv_min(mut self, uv_min: [f32; 2]) -> Self {
self.uv_min = uv_min;
self
}
/// Set uv_max (default `[1.0, 1.0]`)
pub fn uv_max(mut self, uv_max: [f32; 2]) -> Self {
self.uv_max = uv_max;
self
}
/// Set color tint (default: no tint/white `[1.0, 1.0, 1.0, 1.0]`)
pub fn col<C>(mut self, col: C) -> Self
where
C: Into<ImColor32>,
{
self.col = col.into();
self
}
/// Draw the image on the window.
pub fn build(self) {
use std::os::raw::c_void;
unsafe {
sys::ImDrawList_AddImage(
self.draw_list.draw_list,
self.texture_id.id() as *mut c_void,
self.p_min.into(),
self.p_max.into(),
self.uv_min.into(),
self.uv_max.into(),
self.col.into(),
);
}
}
}
/// Represents a image about to be drawn
#[must_use = "should call .build() to draw the object"]
pub struct ImageQuad<'ui> {
texture_id: TextureId,
p1: [f32; 2],
p2: [f32; 2],
p3: [f32; 2],
p4: [f32; 2],
uv1: [f32; 2],
uv2: [f32; 2],
uv3: [f32; 2],
uv4: [f32; 2],
col: ImColor32,
draw_list: &'ui DrawListMut<'ui>,
}
impl<'ui> ImageQuad<'ui> {
/// Typically constructed by [`DrawListMut::add_image_quad`]
pub fn new(
draw_list: &'ui DrawListMut,
texture_id: TextureId,
p1: [f32; 2],
p2: [f32; 2],
p3: [f32; 2],
p4: [f32; 2],
) -> Self {
Self {
texture_id,
p1,
p2,
p3,
p4,
uv1: [0.0, 0.0],
uv2: [1.0, 0.0],
uv3: [1.0, 1.0],
uv4: [0.0, 1.0],
col: [1.0, 1.0, 1.0, 1.0].into(),
draw_list,
}
}
/// Set uv coordinates of each point of the quad. If not called, defaults are:
///
/// ```text
/// uv1: [0.0, 0.0],
/// uv2: [1, 0],
/// uv3: [1, 1],
/// uv4: [0, 1],
/// ```
pub fn uv(mut self, uv1: [f32; 2], uv2: [f32; 2], uv3: [f32; 2], uv4: [f32; 2]) -> Self {
self.uv1 = uv1;
self.uv2 = uv2;
self.uv3 = uv3;
self.uv4 = uv4;
self
}
/// Set color tint (default: no tint/white `[1.0, 1.0, 1.0, 1.0]`)
pub fn col<C>(mut self, col: C) -> Self
where
C: Into<ImColor32>,
{
self.col = col.into();
self
}
/// Draw the image on the window.
pub fn build(self) {
use std::os::raw::c_void;
unsafe {
sys::ImDrawList_AddImageQuad(
self.draw_list.draw_list,
self.texture_id.id() as *mut c_void,
self.p1.into(),
self.p2.into(),
self.p3.into(),
self.p4.into(),
self.uv1.into(),
self.uv2.into(),
self.uv3.into(),
self.uv4.into(),
self.col.into(),
);
}
}
}
/// Represents a image about to be drawn. Similar to [`Image`] but
/// with corners rounded with a given radius
#[must_use = "should call .build() to draw the object"]
pub struct ImageRounded<'ui> {
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
uv_min: [f32; 2],
uv_max: [f32; 2],
col: ImColor32,
rounding: f32,
rounding_corners: CornerFlags,
draw_list: &'ui DrawListMut<'ui>,
}
impl<'ui> ImageRounded<'ui> {
/// Typically constructed by [`DrawListMut::add_image_rounded`]
pub fn new(
draw_list: &'ui DrawListMut,
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
rounding: f32,
) -> Self {
Self {
texture_id,
p_min,
p_max,
uv_min: [0.0, 0.0],
uv_max: [1.0, 1.0],
col: [1.0, 1.0, 1.0, 1.0].into(),
rounding,
rounding_corners: CornerFlags::ALL,
draw_list,
}
}
/// Set uv_min (default `[0.0, 0.0]`)
pub fn uv_min(mut self, uv_min: [f32; 2]) -> Self {
self.uv_min = uv_min;
self
}
/// Set uv_max (default `[1.0, 1.0]`)
pub fn uv_max(mut self, uv_max: [f32; 2]) -> Self {
self.uv_max = uv_max;
self
}
/// Set color tint (default: no tint/white `[1.0, 1.0, 1.0, 1.0]`)
pub fn col<C>(mut self, col: C) -> Self
where
C: Into<ImColor32>,
{
self.col = col.into();
self
}
/// Set flag to indicate rounding on all all corners.
pub fn round_all(mut self, value: bool) -> Self {
self.rounding_corners.set(CornerFlags::ALL, value);
self
}
/// Set flag to indicate if image's top-left corner will be rounded.
pub fn round_top_left(mut self, value: bool) -> Self {
self.rounding_corners.set(CornerFlags::TOP_LEFT, value);
self
}
/// Set flag to indicate if image's top-right corner will be rounded.
pub fn round_top_right(mut self, value: bool) -> Self {
self.rounding_corners.set(CornerFlags::TOP_RIGHT, value);
self
}
/// Set flag to indicate if image's bottom-left corner will be rounded.
pub fn round_bot_left(mut self, value: bool) -> Self {
self.rounding_corners.set(CornerFlags::BOT_LEFT, value);
self
}
/// Set flag to indicate if image's bottom-right corner will be rounded.
pub fn round_bot_right(mut self, value: bool) -> Self {
self.rounding_corners.set(CornerFlags::BOT_RIGHT, value);
self
}
/// Draw the image on the window.
pub fn build(self) {
use std::os::raw::c_void;
unsafe {
sys::ImDrawList_AddImageRounded(
self.draw_list.draw_list,
self.texture_id.id() as *mut c_void,
self.p_min.into(),
self.p_max.into(),
self.uv_min.into(),
self.uv_max.into(),
self.col.into(),
self.rounding,
self.rounding_corners.bits() as i32,
);
}
}
}

View File

@ -113,7 +113,7 @@ impl FontGlyphRanges {
/// Creates a glyph range from a static slice without checking its validity.
///
/// See [`FontRangeGlyph::from_slice`] for more information.
/// See [`FontGlyphRanges::from_slice`] for more information.
///
/// # Safety
///

View File

@ -1,121 +1,164 @@
use bitflags::bitflags;
use std::marker::PhantomData;
use std::os::raw::{c_int, c_void};
use std::ptr;
use crate::legacy::ImGuiInputTextFlags;
use crate::sys;
use crate::{ImStr, ImString, Ui};
bitflags!(
/// Flags for text inputs
#[repr(C)]
pub struct InputTextFlags: u32 {
/// Allow 0123456789.+-*/
const CHARS_DECIMAL = sys::ImGuiInputTextFlags_CharsDecimal;
/// Allow 0123456789ABCDEFabcdef
const CHARS_HEXADECIMAL = sys::ImGuiInputTextFlags_CharsHexadecimal;
/// Turn a..z into A..Z
const CHARS_UPPERCASE = sys::ImGuiInputTextFlags_CharsUppercase;
/// Filter out spaces, tabs
const CHARS_NO_BLANK = sys::ImGuiInputTextFlags_CharsNoBlank;
/// Select entire text when first taking mouse focus
const AUTO_SELECT_ALL = sys::ImGuiInputTextFlags_AutoSelectAll;
/// Return 'true' when Enter is pressed (as opposed to when the value was modified)
const ENTER_RETURNS_TRUE = sys::ImGuiInputTextFlags_EnterReturnsTrue;
/// Call user function on pressing TAB (for completion handling)
const CALLBACK_COMPLETION = sys::ImGuiInputTextFlags_CallbackCompletion;
/// Call user function on pressing Up/Down arrows (for history handling)
const CALLBACK_HISTORY = sys::ImGuiInputTextFlags_CallbackHistory;
/// Call user function every time. User code may query cursor position, modify text buffer.
const CALLBACK_ALWAYS = sys::ImGuiInputTextFlags_CallbackAlways;
/// Call user function to filter character.
const CALLBACK_CHAR_FILTER = sys::ImGuiInputTextFlags_CallbackCharFilter;
/// Pressing TAB input a '\t' character into the text field
const ALLOW_TAB_INPUT = sys::ImGuiInputTextFlags_AllowTabInput;
/// In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is
/// opposite: unfocus with Ctrl+Enter, add line with Enter).
const CTRL_ENTER_FOR_NEW_LINE = sys::ImGuiInputTextFlags_CtrlEnterForNewLine;
/// Disable following the cursor horizontally
const NO_HORIZONTAL_SCROLL = sys::ImGuiInputTextFlags_NoHorizontalScroll;
/// Insert mode
const ALWAYS_INSERT_MODE = sys::ImGuiInputTextFlags_AlwaysInsertMode;
/// Read-only mode
const READ_ONLY = sys::ImGuiInputTextFlags_ReadOnly;
/// Password mode, display all characters as '*'
const PASSWORD = sys::ImGuiInputTextFlags_Password;
/// Disable undo/redo.
const NO_UNDO_REDO = sys::ImGuiInputTextFlags_NoUndoRedo;
/// Allow 0123456789.+-*/eE (Scientific notation input)
const CHARS_SCIENTIFIC = sys::ImGuiInputTextFlags_CharsScientific;
/// Allow buffer capacity resize + notify when the string wants to be resized
const CALLBACK_RESIZE = sys::ImGuiInputTextFlags_CallbackResize;
}
);
macro_rules! impl_text_flags {
($InputType:ident) => {
#[inline]
pub fn flags(mut self, flags: ImGuiInputTextFlags) -> Self {
pub fn flags(mut self, flags: InputTextFlags) -> Self {
self.flags = flags;
self
}
#[inline]
pub fn chars_decimal(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::CharsDecimal, value);
self.flags.set(InputTextFlags::CHARS_DECIMAL, value);
self
}
#[inline]
pub fn chars_hexadecimal(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::CharsHexadecimal, value);
self.flags.set(InputTextFlags::CHARS_HEXADECIMAL, value);
self
}
#[inline]
pub fn chars_uppercase(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::CharsUppercase, value);
self.flags.set(InputTextFlags::CHARS_UPPERCASE, value);
self
}
#[inline]
pub fn chars_noblank(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::CharsNoBlank, value);
self.flags.set(InputTextFlags::CHARS_NO_BLANK, value);
self
}
#[inline]
pub fn auto_select_all(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::AutoSelectAll, value);
self.flags.set(InputTextFlags::AUTO_SELECT_ALL, value);
self
}
#[inline]
pub fn enter_returns_true(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::EnterReturnsTrue, value);
self.flags.set(InputTextFlags::ENTER_RETURNS_TRUE, value);
self
}
#[inline]
pub fn callback_completion(mut self, value: bool) -> Self {
self.flags
.set(ImGuiInputTextFlags::CallbackCompletion, value);
self.flags.set(InputTextFlags::CALLBACK_COMPLETION, value);
self
}
#[inline]
pub fn callback_history(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::CallbackHistory, value);
self.flags.set(InputTextFlags::CALLBACK_HISTORY, value);
self
}
#[inline]
pub fn callback_always(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::CallbackAlways, value);
self.flags.set(InputTextFlags::CALLBACK_ALWAYS, value);
self
}
#[inline]
pub fn callback_char_filter(mut self, value: bool) -> Self {
self.flags
.set(ImGuiInputTextFlags::CallbackCharFilter, value);
self.flags.set(InputTextFlags::CALLBACK_CHAR_FILTER, value);
self
}
#[inline]
pub fn resize_buffer(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::CallbackResize, value);
self.flags.set(InputTextFlags::CALLBACK_RESIZE, value);
self
}
#[inline]
pub fn allow_tab_input(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::AllowTabInput, value);
self.flags.set(InputTextFlags::ALLOW_TAB_INPUT, value);
self
}
#[inline]
pub fn no_horizontal_scroll(mut self, value: bool) -> Self {
self.flags
.set(ImGuiInputTextFlags::NoHorizontalScroll, value);
self.flags.set(InputTextFlags::NO_HORIZONTAL_SCROLL, value);
self
}
#[inline]
pub fn always_insert_mode(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::AlwaysInsertMode, value);
self.flags.set(InputTextFlags::ALWAYS_INSERT_MODE, value);
self
}
#[inline]
pub fn read_only(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::ReadOnly, value);
self.flags.set(InputTextFlags::READ_ONLY, value);
self
}
#[inline]
pub fn password(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::Password, value);
self.flags.set(InputTextFlags::PASSWORD, value);
self
}
#[inline]
pub fn no_undo_redo(mut self, value: bool) -> Self {
self.flags.set(ImGuiInputTextFlags::NoUndoRedo, value);
self.flags.set(InputTextFlags::NO_UNDO_REDO, value);
self
}
};
@ -139,7 +182,7 @@ macro_rules! impl_step_params {
extern "C" fn resize_callback(data: *mut sys::ImGuiInputTextCallbackData) -> c_int {
unsafe {
if (*data).EventFlag == ImGuiInputTextFlags::CallbackResize.bits() {
if (*data).EventFlag == InputTextFlags::CALLBACK_RESIZE.bits() as i32 {
if let Some(buffer) = ((*data).UserData as *mut ImString).as_mut() {
let requested_size = (*data).BufSize as usize;
if requested_size > buffer.capacity_with_nul() {
@ -161,7 +204,7 @@ pub struct InputText<'ui, 'p> {
label: &'p ImStr,
hint: Option<&'p ImStr>,
buf: &'p mut ImString,
flags: ImGuiInputTextFlags,
flags: InputTextFlags,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
@ -171,7 +214,7 @@ impl<'ui, 'p> InputText<'ui, 'p> {
label,
hint: None,
buf,
flags: ImGuiInputTextFlags::empty(),
flags: InputTextFlags::empty(),
_phantom: PhantomData,
}
}
@ -191,7 +234,7 @@ impl<'ui, 'p> InputText<'ui, 'p> {
pub fn build(self) -> bool {
let (ptr, capacity) = (self.buf.as_mut_ptr(), self.buf.capacity_with_nul());
let (callback, data): (sys::ImGuiInputTextCallback, _) = {
if self.flags.contains(ImGuiInputTextFlags::CallbackResize) {
if self.flags.contains(InputTextFlags::CALLBACK_RESIZE) {
(Some(resize_callback), self.buf as *mut _ as *mut c_void)
} else {
(None, ptr::null_mut())
@ -205,7 +248,7 @@ impl<'ui, 'p> InputText<'ui, 'p> {
hint.as_ptr(),
ptr,
capacity,
self.flags.bits(),
self.flags.bits() as i32,
callback,
data,
)
@ -214,7 +257,7 @@ impl<'ui, 'p> InputText<'ui, 'p> {
self.label.as_ptr(),
ptr,
capacity,
self.flags.bits(),
self.flags.bits() as i32,
callback,
data,
)
@ -229,7 +272,7 @@ impl<'ui, 'p> InputText<'ui, 'p> {
pub struct InputTextMultiline<'ui, 'p> {
label: &'p ImStr,
buf: &'p mut ImString,
flags: ImGuiInputTextFlags,
flags: InputTextFlags,
size: [f32; 2],
_phantom: PhantomData<&'ui Ui<'ui>>,
}
@ -239,7 +282,7 @@ impl<'ui, 'p> InputTextMultiline<'ui, 'p> {
InputTextMultiline {
label,
buf,
flags: ImGuiInputTextFlags::empty(),
flags: InputTextFlags::empty(),
size,
_phantom: PhantomData,
}
@ -253,7 +296,7 @@ impl<'ui, 'p> InputTextMultiline<'ui, 'p> {
pub fn build(self) -> bool {
let (ptr, capacity) = (self.buf.as_mut_ptr(), self.buf.capacity_with_nul());
let (callback, data): (sys::ImGuiInputTextCallback, _) = {
if self.flags.contains(ImGuiInputTextFlags::CallbackResize) {
if self.flags.contains(InputTextFlags::CALLBACK_RESIZE) {
(Some(resize_callback), self.buf as *mut _ as *mut c_void)
} else {
(None, ptr::null_mut())
@ -266,7 +309,7 @@ impl<'ui, 'p> InputTextMultiline<'ui, 'p> {
ptr,
capacity,
self.size.into(),
self.flags.bits(),
self.flags.bits() as i32,
callback,
data,
);
@ -282,7 +325,7 @@ pub struct InputInt<'ui, 'p> {
value: &'p mut i32,
step: i32,
step_fast: i32,
flags: ImGuiInputTextFlags,
flags: InputTextFlags,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
@ -293,7 +336,7 @@ impl<'ui, 'p> InputInt<'ui, 'p> {
value,
step: 1,
step_fast: 100,
flags: ImGuiInputTextFlags::empty(),
flags: InputTextFlags::empty(),
_phantom: PhantomData,
}
}
@ -305,7 +348,7 @@ impl<'ui, 'p> InputInt<'ui, 'p> {
self.value as *mut i32,
self.step,
self.step_fast,
self.flags.bits(),
self.flags.bits() as i32,
)
}
}
@ -320,7 +363,7 @@ pub struct InputFloat<'ui, 'p> {
value: &'p mut f32,
step: f32,
step_fast: f32,
flags: ImGuiInputTextFlags,
flags: InputTextFlags,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
@ -331,7 +374,7 @@ impl<'ui, 'p> InputFloat<'ui, 'p> {
value,
step: 0.0,
step_fast: 0.0,
flags: ImGuiInputTextFlags::empty(),
flags: InputTextFlags::empty(),
_phantom: PhantomData,
}
}
@ -344,7 +387,7 @@ impl<'ui, 'p> InputFloat<'ui, 'p> {
self.step,
self.step_fast,
b"%.3f\0".as_ptr() as *const _,
self.flags.bits(),
self.flags.bits() as i32,
)
}
}
@ -359,7 +402,7 @@ macro_rules! impl_input_floatn {
pub struct $InputFloatN<'ui, 'p> {
label: &'p ImStr,
value: &'p mut [f32; $N],
flags: ImGuiInputTextFlags,
flags: InputTextFlags,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
@ -368,7 +411,7 @@ macro_rules! impl_input_floatn {
$InputFloatN {
label,
value,
flags: ImGuiInputTextFlags::empty(),
flags: InputTextFlags::empty(),
_phantom: PhantomData,
}
}
@ -379,7 +422,7 @@ macro_rules! impl_input_floatn {
self.label.as_ptr(),
self.value.as_mut_ptr(),
b"%.3f\0".as_ptr() as *const _,
self.flags.bits(),
self.flags.bits() as i32,
)
}
}
@ -399,7 +442,7 @@ macro_rules! impl_input_intn {
pub struct $InputIntN<'ui, 'p> {
label: &'p ImStr,
value: &'p mut [i32; $N],
flags: ImGuiInputTextFlags,
flags: InputTextFlags,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
@ -408,7 +451,7 @@ macro_rules! impl_input_intn {
$InputIntN {
label,
value,
flags: ImGuiInputTextFlags::empty(),
flags: InputTextFlags::empty(),
_phantom: PhantomData,
}
}
@ -418,7 +461,7 @@ macro_rules! impl_input_intn {
sys::$igInputIntN(
self.label.as_ptr(),
self.value.as_mut_ptr(),
self.flags.bits(),
self.flags.bits() as i32,
)
}
}

View File

@ -1,84 +0,0 @@
#![allow(non_upper_case_globals)]
use bitflags::bitflags;
use std::os::raw::c_int;
use crate::widget::tree::TreeNodeFlags;
bitflags!(
/// Flags for indictating which corner of a rectangle should be rounded
#[repr(C)]
pub struct ImDrawCornerFlags: c_int {
const TopLeft = 1;
const TopRight = 1 << 1;
const BotLeft = 1 << 2;
const BotRight = 1 << 3;
const Top = ImDrawCornerFlags::TopLeft.bits
| ImDrawCornerFlags::TopRight.bits;
const Bot = ImDrawCornerFlags::BotLeft.bits
| ImDrawCornerFlags::BotRight.bits;
const Left = ImDrawCornerFlags::TopLeft.bits
| ImDrawCornerFlags::BotLeft.bits;
const Right = ImDrawCornerFlags::TopRight.bits
| ImDrawCornerFlags::BotRight.bits;
const All = 0xF;
}
);
bitflags!(
/// Draw list flags
#[repr(C)]
pub struct ImDrawListFlags: c_int {
const AntiAliasedLines = 1;
const AntiAliasedLinesUseTex = 1 << 1;
const AntiAliasedFill = 1 << 2;
const AllowVtxOffset = 1 << 3;
}
);
bitflags!(
/// Flags for text inputs
#[repr(C)]
pub struct ImGuiInputTextFlags: c_int {
/// Allow 0123456789.+-*/
const CharsDecimal = 1;
/// Allow 0123456789ABCDEFabcdef
const CharsHexadecimal = 1 << 1;
/// Turn a..z into A..Z
const CharsUppercase = 1 << 2;
/// Filter out spaces, tabs
const CharsNoBlank = 1 << 3;
/// Select entire text when first taking mouse focus
const AutoSelectAll = 1 << 4;
/// Return 'true' when Enter is pressed (as opposed to when the value was modified)
const EnterReturnsTrue = 1 << 5;
/// Call user function on pressing TAB (for completion handling)
const CallbackCompletion = 1 << 6;
/// Call user function on pressing Up/Down arrows (for history handling)
const CallbackHistory = 1 << 7;
/// Call user function every time. User code may query cursor position, modify text buffer.
const CallbackAlways = 1 << 8;
/// Call user function to filter character.
const CallbackCharFilter = 1 << 9;
/// Pressing TAB input a '\t' character into the text field
const AllowTabInput = 1 << 10;
/// In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is
/// opposite: unfocus with Ctrl+Enter, add line with Enter).
const CtrlEnterForNewLine = 1 << 11;
/// Disable following the cursor horizontally
const NoHorizontalScroll = 1 << 12;
/// Insert mode
const AlwaysInsertMode = 1 << 13;
/// Read-only mode
const ReadOnly = 1 << 14;
/// Password mode, display all characters as '*'
const Password = 1 << 15;
/// Disable undo/redo.
const NoUndoRedo = 1 << 16;
/// Allow 0123456789.+-*/eE (Scientific notation input)
const CharsScientific = 1 << 17;
/// Allow buffer capacity resize + notify when the string wants to be resized
const CallbackResize = 1 << 18;
}
);
pub type ImGuiTreeNodeFlags = TreeNodeFlags;

View File

@ -25,7 +25,6 @@ pub use self::input_widget::{
};
pub use self::io::*;
pub use self::layout::*;
pub use self::legacy::*;
pub use self::list_clipper::ListClipper;
pub use self::plothistogram::PlotHistogram;
pub use self::plotlines::PlotLines;
@ -62,14 +61,13 @@ pub mod color;
mod columns;
mod context;
pub mod drag_drop;
mod draw_list;
pub mod draw_list;
mod fonts;
mod input;
mod input_widget;
pub mod internal;
mod io;
mod layout;
mod legacy;
mod list_clipper;
mod plothistogram;
mod plotlines;