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
//! Helpers for UI alignment.
use arcdps::imgui::Ui;
/// Render state for left alignment.
#[derive(Debug, Clone, Copy)]
pub struct LeftAlign {
first: bool,
spacing: f32,
}
impl LeftAlign {
/// Starts rendering items in left alignment.
///
/// Items are passed from **left to right**.
pub fn build() -> Self {
Self::with_spacing(5.0)
}
/// Starts rendering items in left alignment with a custom spacing.
///
/// Items are passed from **left to right**.
pub fn with_spacing(spacing: f32) -> Self {
Self {
first: false,
spacing,
}
}
/// Renders the next item.
///
/// Items are passed from **left to right**.
pub fn item(&mut self, ui: &Ui, render: impl FnOnce()) {
self.item_with_spacing(ui, self.spacing, render);
}
/// Renders the next item with a temporary spacing override.
///
/// Items are passed from **left to right**.
pub fn item_with_spacing(&mut self, ui: &Ui, spacing: f32, render: impl FnOnce()) {
// prepare
if self.first {
self.first = false;
} else {
ui.same_line_with_spacing(0.0, spacing);
}
// render item
render();
}
}
/// Render state for right alignment.
#[derive(Debug, Clone, Copy)]
pub struct RightAlign {
spacing: f32,
accumulated: f32,
}
impl RightAlign {
/// Starts rendering items in right alignment.
///
/// Items are passed from **right to left**.
pub fn build() -> Self {
Self::with_spacing(5.0)
}
/// Starts rendering items in right alignment with a custom spacing.
///
/// Items are passed from **right to left**.
pub fn with_spacing(spacing: f32) -> Self {
Self {
spacing,
accumulated: 0.0,
}
}
/// Renders the next item.
///
/// Items are passed from **right to left**.
///
/// The item width will be used for alignment and updated with the correct width after render.
/// It can be a guessed default on the first render.
pub fn item(&mut self, ui: &Ui, item_width: &mut f32, render: impl FnOnce()) {
self.item_with_spacing(ui, self.spacing, item_width, render)
}
/// Renders the next item with a temporary spacing override.
///
/// Items are passed from **right to left**.
///
/// The item width will be used for alignment and updated with the correct width after render.
/// It can be a guessed default on the first render.
pub fn item_with_spacing(
&mut self,
ui: &Ui,
spacing: f32,
item_width: &mut f32,
render: impl FnOnce(),
) {
// prepare alignment
let [window_x, _] = ui.window_content_region_max();
ui.same_line_with_pos(window_x - self.accumulated - *item_width);
// render item
render();
// update item width & accumulated with actual size
*item_width = ui.item_rect_size()[0];
self.accumulated += *item_width + spacing;
}
}