mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
init draft
This commit is contained in:
parent
7122366a43
commit
7b644bf159
@ -41,29 +41,27 @@ fn example_1(ui: &Ui, state: &mut State) {
|
||||
ui.text("Unsigned: u8 u16 u32 u64");
|
||||
ui.text("Floats: f32 f64");
|
||||
|
||||
Slider::new(im_str!("u8 value"))
|
||||
Slider::new(im_str!("u8 value"), 0, 255)
|
||||
.build(ui, &mut state.u8_value);
|
||||
|
||||
Slider::new(im_str!("f32 value"))
|
||||
Slider::new(im_str!("f32 value"), -f32::MIN, f32::MAX)
|
||||
.build(ui, &mut state.f32_value);
|
||||
|
||||
ui.separator();
|
||||
ui.text("Slider range can be limited:");
|
||||
Slider::new(im_str!("i32 value with range"))
|
||||
.range(-999 ..= 999)
|
||||
Slider::new(im_str!("i32 value with range"), -999, 999)
|
||||
.build(ui, &mut state.i32_value);
|
||||
ui.text("Note that for 32-bit/64-bit types, sliders are always limited to half of the natural type range!");
|
||||
|
||||
ui.separator();
|
||||
ui.text("Value formatting can be customized with a C-style printf string:");
|
||||
Slider::new(im_str!("f64 value with custom formatting"))
|
||||
.range(-999_999_999.0 ..= 999_999_999.0)
|
||||
Slider::new(im_str!("f64 value with custom formatting"), -999_999_999.0, 999_999_999.0)
|
||||
.display_format(im_str!("%09.0f"))
|
||||
.build(ui, &mut state.f64_formatted);
|
||||
|
||||
ui.separator();
|
||||
ui.text("Vertical sliders require a size parameter but otherwise work in a similar way:");
|
||||
VerticalSlider::new(im_str!("vertical\nu8 value"), [50.0, 50.0])
|
||||
VerticalSlider::new(im_str!("vertical\nu8 value"), [50.0, 50.0], u8::MIN, u8::MAX)
|
||||
.build(ui, &mut state.u8_value);
|
||||
});
|
||||
}
|
||||
@ -74,11 +72,11 @@ fn example_2(ui: &Ui, state: &mut State) {
|
||||
.position([20.0, 120.0], Condition::Appearing);
|
||||
w.build(ui, || {
|
||||
ui.text("You can easily build a slider group from an array of values:");
|
||||
Slider::new(im_str!("[u8; 4]")).build_array(ui, &mut state.array);
|
||||
Slider::new(im_str!("[u8; 4]"), 0, u8::MAX).build_array(ui, &mut state.array);
|
||||
|
||||
ui.text("You don't need to use arrays with known length; arbitrary slices can be used:");
|
||||
let slice: &mut [u8] = &mut state.array[1..=2];
|
||||
Slider::new(im_str!("subslice")).build_array(ui, slice);
|
||||
Slider::new(im_str!("subslice"), 0, u8::MAX).build_array(ui, slice);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -448,7 +448,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
));
|
||||
ui.spacing();
|
||||
|
||||
Slider::new(im_str!("Wrap width")).range(-20.0 ..= 600.0)
|
||||
Slider::new(im_str!("Wrap width"), -20.0, 600.0)
|
||||
.display_format(im_str!("%.0f"))
|
||||
.build(ui, &mut state.wrap_width);
|
||||
|
||||
@ -545,7 +545,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
.step(0.01)
|
||||
.step_fast(1.0)
|
||||
.build();
|
||||
Drag::new(im_str!("drag float")).range(-1.0..=1.0).speed(0.001).build(ui, &mut state.f0);
|
||||
Drag::new(im_str!("drag float")).range(-1.0, 1.0).speed(0.001).build(ui, &mut state.f0);
|
||||
ui.input_float3(im_str!("input float3"), &mut state.vec3f)
|
||||
.build();
|
||||
ColorEdit::new(im_str!("color 1"), &mut state.col1).build(ui);
|
||||
@ -899,9 +899,7 @@ fn show_example_menu_file<'a>(ui: &Ui<'a>, state: &mut FileMenuState) {
|
||||
ui.text(format!("Scrolling Text {}", i));
|
||||
}
|
||||
});
|
||||
Slider::new(im_str!("Value"))
|
||||
.range(0.0..=1.0)
|
||||
.build(ui, &mut state.f);
|
||||
Slider::new(im_str!("Value"), 0.0, 1.0).build(ui, &mut state.f);
|
||||
|
||||
ui.input_float(im_str!("Input"), &mut state.f)
|
||||
.step(0.1)
|
||||
@ -936,9 +934,7 @@ fn show_example_app_auto_resize(ui: &Ui, state: &mut AutoResizeState, opened: &m
|
||||
Note that you probably don't want to query the window size to
|
||||
output your content because that would create a feedback loop.",
|
||||
);
|
||||
Slider::new(im_str!("Number of lines"))
|
||||
.range(1..=20)
|
||||
.build(ui, &mut state.lines);
|
||||
Slider::new(im_str!("Number of lines"), 1, 20).build(ui, &mut state.lines);
|
||||
for i in 0..state.lines {
|
||||
ui.text(format!("{:2$}This is line {}", "", i, i as usize * 4));
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
//! Internal raw utilities (don't use unless you know what you're doing!)
|
||||
|
||||
use std::ops::{RangeFrom, RangeInclusive, RangeToInclusive};
|
||||
use std::slice;
|
||||
|
||||
/// A generic version of the raw imgui-sys ImVector struct types
|
||||
@ -127,94 +126,34 @@ pub enum DataType {
|
||||
/// representation in memory as the primitive value described by the associated `KIND` constant.
|
||||
pub unsafe trait DataTypeKind: Copy {
|
||||
const KIND: DataType;
|
||||
const SLIDER_MIN: Self;
|
||||
const SLIDER_MAX: Self;
|
||||
}
|
||||
unsafe impl DataTypeKind for i8 {
|
||||
const KIND: DataType = DataType::I8;
|
||||
const SLIDER_MIN: Self = std::i8::MIN;
|
||||
const SLIDER_MAX: Self = std::i8::MAX;
|
||||
}
|
||||
unsafe impl DataTypeKind for u8 {
|
||||
const KIND: DataType = DataType::U8;
|
||||
const SLIDER_MIN: Self = std::u8::MIN;
|
||||
const SLIDER_MAX: Self = std::u8::MAX;
|
||||
}
|
||||
unsafe impl DataTypeKind for i16 {
|
||||
const KIND: DataType = DataType::I16;
|
||||
const SLIDER_MIN: Self = std::i16::MIN;
|
||||
const SLIDER_MAX: Self = std::i16::MAX;
|
||||
}
|
||||
unsafe impl DataTypeKind for u16 {
|
||||
const KIND: DataType = DataType::U16;
|
||||
const SLIDER_MIN: Self = std::u16::MIN;
|
||||
const SLIDER_MAX: Self = std::u16::MAX;
|
||||
}
|
||||
unsafe impl DataTypeKind for i32 {
|
||||
const KIND: DataType = DataType::I32;
|
||||
const SLIDER_MIN: Self = std::i32::MIN / 2;
|
||||
const SLIDER_MAX: Self = std::i32::MAX / 2;
|
||||
}
|
||||
unsafe impl DataTypeKind for u32 {
|
||||
const KIND: DataType = DataType::U32;
|
||||
const SLIDER_MIN: Self = std::u32::MIN / 2;
|
||||
const SLIDER_MAX: Self = std::u32::MAX / 2;
|
||||
}
|
||||
unsafe impl DataTypeKind for i64 {
|
||||
const KIND: DataType = DataType::I64;
|
||||
const SLIDER_MIN: Self = std::i64::MIN / 2;
|
||||
const SLIDER_MAX: Self = std::i64::MAX / 2;
|
||||
}
|
||||
unsafe impl DataTypeKind for u64 {
|
||||
const KIND: DataType = DataType::U64;
|
||||
const SLIDER_MIN: Self = std::u64::MIN / 2;
|
||||
const SLIDER_MAX: Self = std::u64::MAX / 2;
|
||||
}
|
||||
unsafe impl DataTypeKind for f32 {
|
||||
const KIND: DataType = DataType::F32;
|
||||
const SLIDER_MIN: Self = std::f32::MIN / 2.0;
|
||||
const SLIDER_MAX: Self = std::f32::MAX / 2.0;
|
||||
}
|
||||
unsafe impl DataTypeKind for f64 {
|
||||
const KIND: DataType = DataType::F64;
|
||||
const SLIDER_MIN: Self = std::f64::MIN / 2.0;
|
||||
const SLIDER_MAX: Self = std::f64::MAX / 2.0;
|
||||
}
|
||||
|
||||
pub trait InclusiveRangeBounds<T: Copy> {
|
||||
fn start_bound(&self) -> Option<&T>;
|
||||
fn end_bound(&self) -> Option<&T>;
|
||||
}
|
||||
|
||||
impl<T: Copy> InclusiveRangeBounds<T> for RangeFrom<T> {
|
||||
#[inline]
|
||||
fn start_bound(&self) -> Option<&T> {
|
||||
Some(&self.start)
|
||||
}
|
||||
#[inline]
|
||||
fn end_bound(&self) -> Option<&T> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> InclusiveRangeBounds<T> for RangeInclusive<T> {
|
||||
#[inline]
|
||||
fn start_bound(&self) -> Option<&T> {
|
||||
Some(self.start())
|
||||
}
|
||||
#[inline]
|
||||
fn end_bound(&self) -> Option<&T> {
|
||||
Some(self.end())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> InclusiveRangeBounds<T> for RangeToInclusive<T> {
|
||||
#[inline]
|
||||
fn start_bound(&self) -> Option<&T> {
|
||||
None
|
||||
}
|
||||
#[inline]
|
||||
fn end_bound(&self) -> Option<&T> {
|
||||
Some(&self.end)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr;
|
||||
|
||||
use crate::internal::{DataTypeKind, InclusiveRangeBounds};
|
||||
use crate::internal::DataTypeKind;
|
||||
use crate::string::ImStr;
|
||||
use crate::sys;
|
||||
use crate::widget::slider::SliderFlags;
|
||||
@ -34,9 +34,9 @@ impl<'a, T: DataTypeKind> Drag<'a, T> {
|
||||
}
|
||||
/// Sets the range (inclusive)
|
||||
#[inline]
|
||||
pub fn range<R: InclusiveRangeBounds<T>>(mut self, range: R) -> Self {
|
||||
self.min = range.start_bound().copied();
|
||||
self.max = range.end_bound().copied();
|
||||
pub fn range(mut self, min: T, max: T) -> Self {
|
||||
self.min = Some(min);
|
||||
self.max = Some(max);
|
||||
self
|
||||
}
|
||||
/// Sets the value increment for a movement of one pixel.
|
||||
@ -140,9 +140,9 @@ impl<'a, T: DataTypeKind> DragRange<'a, T> {
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn range<R: InclusiveRangeBounds<T>>(mut self, range: R) -> Self {
|
||||
self.min = range.start_bound().copied();
|
||||
self.max = range.end_bound().copied();
|
||||
pub fn range(mut self, min: T, max: T) -> Self {
|
||||
self.min = Some(min);
|
||||
self.max = Some(max);
|
||||
self
|
||||
}
|
||||
/// Sets the value increment for a movement of one pixel.
|
||||
|
||||
@ -2,7 +2,7 @@ use bitflags::bitflags;
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr;
|
||||
|
||||
use crate::internal::{DataTypeKind, InclusiveRangeBounds};
|
||||
use crate::internal::DataTypeKind;
|
||||
use crate::string::ImStr;
|
||||
use crate::sys;
|
||||
use crate::Ui;
|
||||
@ -38,42 +38,32 @@ pub struct Slider<'a, T: DataTypeKind> {
|
||||
impl<'a, T: DataTypeKind> Slider<'a, T> {
|
||||
/// Constructs a new slider builder with the given range.
|
||||
#[doc(alias = "SliderScalar", alias = "SliderScalarN")]
|
||||
pub fn new(label: &ImStr) -> Slider<T> {
|
||||
pub fn new(label: &ImStr, min: T, max: T) -> Slider<T> {
|
||||
Slider {
|
||||
label,
|
||||
min: T::SLIDER_MIN,
|
||||
max: T::SLIDER_MAX,
|
||||
min,
|
||||
max,
|
||||
display_format: None,
|
||||
flags: SliderFlags::empty(),
|
||||
}
|
||||
}
|
||||
/// Sets the range (inclusive)
|
||||
///
|
||||
/// The argument uses the standard Rust [`std::ops::Range`] syntax.
|
||||
///
|
||||
/// For example, to set both the min and max values:
|
||||
/// Sets the range inclusively, such that both values given
|
||||
/// are valid values which the slider can be dragged to.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use imgui::im_str;
|
||||
/// imgui::Slider::new(im_str!("Example"))
|
||||
/// .range(1 ..= 10)
|
||||
/// .range(i8::MIN, i8::MAX)
|
||||
/// // Remember to call .build(&ui)
|
||||
/// ;
|
||||
/// ```
|
||||
///
|
||||
/// To set only the max value, using the default minimum value:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use imgui::im_str;
|
||||
/// imgui::Slider::new(im_str!("Example"))
|
||||
/// .range(..= 10)
|
||||
/// // Remember to call .build(&ui)
|
||||
/// ;
|
||||
/// ```
|
||||
/// It is safe, though up to C++ Dear ImGui, on how to handle when
|
||||
/// `min > max`.
|
||||
#[inline]
|
||||
pub fn range<R: InclusiveRangeBounds<T>>(mut self, range: R) -> Self {
|
||||
self.min = range.start_bound().copied().unwrap_or(T::SLIDER_MIN);
|
||||
self.max = range.end_bound().copied().unwrap_or(T::SLIDER_MAX);
|
||||
pub fn range(mut self, min: T, max: T) -> Self {
|
||||
self.min = min;
|
||||
self.max = max;
|
||||
self
|
||||
}
|
||||
/// Sets the display format using *a C-style printf string*
|
||||
@ -142,21 +132,32 @@ pub struct VerticalSlider<'a, T: DataTypeKind + Copy> {
|
||||
impl<'a, T: DataTypeKind> VerticalSlider<'a, T> {
|
||||
/// Constructs a new vertical slider builder with the given size and range.
|
||||
#[doc(alias = "VSliderScalar")]
|
||||
pub fn new(label: &ImStr, size: [f32; 2]) -> VerticalSlider<T> {
|
||||
pub fn new(label: &ImStr, size: [f32; 2], min: T, max: T) -> VerticalSlider<T> {
|
||||
VerticalSlider {
|
||||
label,
|
||||
size,
|
||||
min: T::SLIDER_MIN,
|
||||
max: T::SLIDER_MAX,
|
||||
min,
|
||||
max,
|
||||
display_format: None,
|
||||
flags: SliderFlags::empty(),
|
||||
}
|
||||
}
|
||||
/// Sets the range (inclusive)
|
||||
|
||||
///
|
||||
/// ```rust
|
||||
/// # use imgui::im_str;
|
||||
/// imgui::VerticalSlider::new(im_str!("Example"))
|
||||
/// .range(i8::MIN, i8::MAX)
|
||||
/// // Remember to call .build(&ui)
|
||||
/// ;
|
||||
/// ```
|
||||
///
|
||||
/// It is safe, though up to C++ Dear ImGui, on how to handle when
|
||||
/// `min > max`.
|
||||
#[inline]
|
||||
pub fn range<R: InclusiveRangeBounds<T>>(mut self, range: R) -> Self {
|
||||
self.min = range.start_bound().copied().unwrap_or(T::SLIDER_MIN);
|
||||
self.max = range.end_bound().copied().unwrap_or(T::SLIDER_MAX);
|
||||
pub fn range(mut self, min: T, max: T) -> Self {
|
||||
self.min = min;
|
||||
self.max = max;
|
||||
self
|
||||
}
|
||||
/// Sets the display format using *a C-style printf string*
|
||||
@ -204,7 +205,8 @@ pub struct AngleSlider<'a> {
|
||||
}
|
||||
|
||||
impl<'a> AngleSlider<'a> {
|
||||
/// Constructs a new angle slider builder.
|
||||
/// Constructs a new angle slider builder, where its minimum defaults to -360.0 and
|
||||
/// maximum defaults to 360.0
|
||||
#[doc(alias = "SliderAngle")]
|
||||
pub fn new(label: &ImStr) -> AngleSlider {
|
||||
AngleSlider {
|
||||
@ -215,11 +217,21 @@ impl<'a> AngleSlider<'a> {
|
||||
flags: SliderFlags::empty(),
|
||||
}
|
||||
}
|
||||
/// Sets the range (in degrees, inclusive)
|
||||
/// Sets the range in degrees (inclusive)
|
||||
/// ```rust
|
||||
/// # use imgui::im_str;
|
||||
/// imgui::AngleSlider::new(im_str!("Example"))
|
||||
/// .range_degrees(-20.0, 20.0)
|
||||
/// // Remember to call .build(&ui)
|
||||
/// ;
|
||||
/// ```
|
||||
///
|
||||
/// It is safe, though up to C++ Dear ImGui, on how to handle when
|
||||
/// `min > max`.
|
||||
#[inline]
|
||||
pub fn range_degrees<R: InclusiveRangeBounds<f32>>(mut self, range: R) -> Self {
|
||||
self.min_degrees = range.start_bound().copied().unwrap_or(-360.0);
|
||||
self.max_degrees = range.end_bound().copied().unwrap_or(360.0);
|
||||
pub fn range_degrees(mut self, min_degrees: f32, max_degrees: f32) -> Self {
|
||||
self.min_degrees = min_degrees;
|
||||
self.max_degrees = max_degrees;
|
||||
self
|
||||
}
|
||||
/// Sets the minimum value (in degrees)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user