diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index d3db514..b7cd6ab 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -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 diff --git a/imgui-examples/examples/custom_textures.rs b/imgui-examples/examples/custom_textures.rs index 5080ffa..c1cce95 100644 --- a/imgui-examples/examples/custom_textures.rs +++ b/imgui-examples/examples/custom_textures.rs @@ -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(); + } + } }); } } diff --git a/imgui/src/draw_list.rs b/imgui/src/draw_list.rs index 02092d3..43f4458 100644 --- a/imgui/src/draw_list.rs +++ b/imgui/src/draw_list.rs @@ -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(draw_list: &'ui DrawListMut, center: [f32; 2], radius: f32, color: C) -> Self where C: Into, @@ -567,7 +671,8 @@ pub struct BezierCurve<'ui> { } impl<'ui> BezierCurve<'ui> { - fn new( + /// Typically constructed by [`DrawListMut::add_bezier_curve`] + pub fn new( 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(mut self, col: C) -> Self + where + C: Into, + { + 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(mut self, col: C) -> Self + where + C: Into, + { + 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(mut self, col: C) -> Self + where + C: Into, + { + 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, + ); + } + } +} diff --git a/imgui/src/fonts/glyph_ranges.rs b/imgui/src/fonts/glyph_ranges.rs index 4ba7c45..dcadeb0 100644 --- a/imgui/src/fonts/glyph_ranges.rs +++ b/imgui/src/fonts/glyph_ranges.rs @@ -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 /// diff --git a/imgui/src/input_widget.rs b/imgui/src/input_widget.rs index a5367ce..eeb592b 100644 --- a/imgui/src/input_widget.rs +++ b/imgui/src/input_widget.rs @@ -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, ) } } diff --git a/imgui/src/legacy.rs b/imgui/src/legacy.rs deleted file mode 100644 index 79c6bf7..0000000 --- a/imgui/src/legacy.rs +++ /dev/null @@ -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; diff --git a/imgui/src/lib.rs b/imgui/src/lib.rs index 1fac42b..7bf2756 100644 --- a/imgui/src/lib.rs +++ b/imgui/src/lib.rs @@ -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;