1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
use bitflags::bitflags;
use crate::sys;
use crate::Ui;
bitflags!(
/// Flags for selectables
#[repr(transparent)]
pub struct SelectableFlags: u32 {
/// Clicking this don't close parent popup window
const DONT_CLOSE_POPUPS = sys::ImGuiSelectableFlags_DontClosePopups;
/// Selectable frame can span all columns (text will still fit in current column)
const SPAN_ALL_COLUMNS = sys::ImGuiSelectableFlags_SpanAllColumns;
/// Generate press events on double clicks too
const ALLOW_DOUBLE_CLICK = sys::ImGuiSelectableFlags_AllowDoubleClick;
/// Cannot be selected, display greyed out text
const DISABLED = sys::ImGuiSelectableFlags_Disabled;
/// (WIP) Hit testing to allow subsequent willdgets to overlap this one
const ALLOW_ITEM_OVERLAP = sys::ImGuiSelectableFlags_AllowItemOverlap;
}
);
/// Builder for a selectable widget.
#[derive(Copy, Clone, Debug)]
#[must_use]
pub struct Selectable<T> {
label: T,
selected: bool,
flags: SelectableFlags,
size: [f32; 2],
}
impl<T: AsRef<str>> Selectable<T> {
/// Constructs a new selectable builder.
#[inline]
#[doc(alias = "Selectable")]
pub fn new(label: T) -> Self {
Selectable {
label,
selected: false,
flags: SelectableFlags::empty(),
size: [0.0, 0.0],
}
}
/// Replaces all current settings with the given flags
#[inline]
pub fn flags(mut self, flags: SelectableFlags) -> Self {
self.flags = flags;
self
}
/// Sets the selected state of the selectable
#[inline]
pub fn selected(mut self, selected: bool) -> Self {
self.selected = selected;
self
}
/// Enables/disables closing parent popup window on click.
///
/// Default: enabled
#[inline]
pub fn close_popups(mut self, value: bool) -> Self {
self.flags.set(SelectableFlags::DONT_CLOSE_POPUPS, !value);
self
}
/// Enables/disables full column span (text will still fit in the current column).
///
/// Default: disabled
#[inline]
pub fn span_all_columns(mut self, value: bool) -> Self {
self.flags.set(SelectableFlags::SPAN_ALL_COLUMNS, value);
self
}
/// Enables/disables click event generation on double clicks.
///
/// Default: disabled
#[inline]
pub fn allow_double_click(mut self, value: bool) -> Self {
self.flags.set(SelectableFlags::ALLOW_DOUBLE_CLICK, value);
self
}
/// Enables/disables the selectable.
///
/// When disabled, it cannot be selected and the text uses the disabled text color.
///
/// Default: disabled
#[inline]
pub fn disabled(mut self, value: bool) -> Self {
self.flags.set(SelectableFlags::DISABLED, value);
self
}
/// Sets the size of the selectable.
///
/// For the X axis:
///
/// - `> 0.0`: use given width
/// - `= 0.0`: use remaining width
///
/// For the Y axis:
///
/// - `> 0.0`: use given height
/// - `= 0.0`: use label height
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
self
}
/// Builds the selectable.
///
/// Returns true if the selectable was clicked.
pub fn build(self, ui: &Ui<'_>) -> bool {
unsafe {
sys::igSelectable_Bool(
ui.scratch_txt(self.label),
self.selected,
self.flags.bits() as i32,
self.size.into(),
)
}
}
/// Builds the selectable using a mutable reference to selected state.
pub fn build_with_ref(self, ui: &Ui<'_>, selected: &mut bool) -> bool {
if self.selected(*selected).build(ui) {
*selected = !*selected;
true
} else {
false
}
}
}