[doc] improve Egui documentation
This commit is contained in:
parent
61cdec8fca
commit
b79c76b9ce
17 changed files with 124 additions and 87 deletions
|
@ -1,11 +1,11 @@
|
||||||
pub mod area;
|
pub(crate) mod area;
|
||||||
pub mod collapsing_header;
|
pub(crate) mod collapsing_header;
|
||||||
pub mod frame;
|
pub(crate) mod frame;
|
||||||
pub mod menu;
|
pub(crate) mod menu;
|
||||||
pub mod popup;
|
pub(crate) mod popup;
|
||||||
pub mod resize;
|
pub(crate) mod resize;
|
||||||
pub mod scroll_area;
|
pub(crate) mod scroll_area;
|
||||||
pub mod window;
|
pub(crate) mod window;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
area::Area, collapsing_header::CollapsingHeader, frame::Frame, popup::*, resize::Resize,
|
area::Area, collapsing_header::CollapsingHeader, frame::Frame, popup::*, resize::Resize,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{widgets::*, *};
|
use crate::{paint::*, widgets::*, *};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{color::*, containers::*, demos::FractalClock, widgets::*, *};
|
use crate::{color::*, containers::*, demos::FractalClock, paint::*, widgets::*, *};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -298,15 +298,9 @@ impl Widgets {
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
if ui.add(radio(self.radio == 0, "First")).clicked {
|
ui.radio_value("First", &mut self.radio, 0);
|
||||||
self.radio = 0;
|
ui.radio_value("Second", &mut self.radio, 1);
|
||||||
}
|
ui.radio_value("Final", &mut self.radio, 2);
|
||||||
if ui.add(radio(self.radio == 1, "Second")).clicked {
|
|
||||||
self.radio = 1;
|
|
||||||
}
|
|
||||||
if ui.add(radio(self.radio == 2, "Final")).clicked {
|
|
||||||
self.radio = 2;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.add(Checkbox::new(&mut self.button_enabled, "Button enabled"));
|
ui.add(Checkbox::new(&mut self.button_enabled, "Button enabled"));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{containers::*, widgets::*, *};
|
use crate::{containers::*, paint::PaintCmd, widgets::*, *};
|
||||||
|
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "with_serde", serde(default))]
|
#[cfg_attr(feature = "with_serde", serde(default))]
|
||||||
|
|
|
@ -1,34 +1,32 @@
|
||||||
//! Egui tracks widgets frame-to-frame using `Id`s.
|
// TODO: have separate types `PositionId` and `UniqueId`. ?
|
||||||
//!
|
|
||||||
//! For instance, if you start dragging a slider one frame, egui stores
|
|
||||||
//! the sliders `Id` as the current active id so that next frame when
|
|
||||||
//! you move the mouse the same slider changes, even if the mouse has
|
|
||||||
//! moved outside the slider.
|
|
||||||
//!
|
|
||||||
//! For some widgets `Id`s are also used to persist some state about the
|
|
||||||
//! widgets, such as Window position or wether not a collapsing header region is open.
|
|
||||||
//!
|
|
||||||
//! This implicates that the `Id`s must be unqiue.
|
|
||||||
//!
|
|
||||||
//! For simple things like sliders and buttons that don't have any memory and
|
|
||||||
//! doesn't move we can use the location of the widget as a source of identity.
|
|
||||||
//! For instance, a slider only needs a unique and persistent ID while you are
|
|
||||||
//! dragging the slider. As long as it is still while moving, that is fine.
|
|
||||||
//!
|
|
||||||
//! For things that need to persist state even after moving (windows, collapsing headers)
|
|
||||||
//! the location of the widgets is obviously not good enough. For instance,
|
|
||||||
//! a collapsing region needs to remember wether or not it is open even
|
|
||||||
//! if the layout next frame is different and the collapsing is not lower down
|
|
||||||
//! on the screen.
|
|
||||||
//!
|
|
||||||
//! Then there are widgets that need no identifiers at all, like labels,
|
|
||||||
//! because they have no state nor are interacted with.
|
|
||||||
//!
|
|
||||||
//! So we have two type of Ids: `PositionId` and `UniqueId`.
|
|
||||||
//! TODO: have separate types for `PositionId` and `UniqueId`.
|
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
/// Egui tracks widgets frame-to-frame using `Id`s.
|
||||||
|
///
|
||||||
|
/// For instance, if you start dragging a slider one frame, egui stores
|
||||||
|
/// the sliders `Id` as the current active id so that next frame when
|
||||||
|
/// you move the mouse the same slider changes, even if the mouse has
|
||||||
|
/// moved outside the slider.
|
||||||
|
///
|
||||||
|
/// For some widgets `Id`s are also used to persist some state about the
|
||||||
|
/// widgets, such as Window position or wether not a collapsing header region is open.
|
||||||
|
///
|
||||||
|
/// This implies that the `Id`s must be unqiue.
|
||||||
|
///
|
||||||
|
/// For simple things like sliders and buttons that don't have any memory and
|
||||||
|
/// doesn't move we can use the location of the widget as a source of identity.
|
||||||
|
/// For instance, a slider only needs a unique and persistent ID while you are
|
||||||
|
/// dragging the slider. As long as it is still while moving, that is fine.
|
||||||
|
///
|
||||||
|
/// For things that need to persist state even after moving (windows, collapsing headers)
|
||||||
|
/// the location of the widgets is obviously not good enough. For instance,
|
||||||
|
/// a collapsing region needs to remember wether or not it is open even
|
||||||
|
/// if the layout next frame is different and the collapsing is not lower down
|
||||||
|
/// on the screen.
|
||||||
|
///
|
||||||
|
/// Then there are widgets that need no identifiers at all, like labels,
|
||||||
|
/// because they have no state nor are interacted with.
|
||||||
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Id(u64);
|
pub struct Id(u64);
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl Layer {
|
||||||
/// Each `PaintCmd` is paired with a clip rectangle.
|
/// Each `PaintCmd` is paired with a clip rectangle.
|
||||||
type PaintList = Vec<(Rect, PaintCmd)>;
|
type PaintList = Vec<(Rect, PaintCmd)>;
|
||||||
|
|
||||||
/// TODO: improve this
|
// TODO: improve this
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct GraphicLayers(AHashMap<Layer, PaintList>);
|
pub struct GraphicLayers(AHashMap<Layer, PaintList>);
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl Default for Align {
|
||||||
|
|
||||||
/// Used e.g. to anchor a piece of text to a part of the rectangle.
|
/// Used e.g. to anchor a piece of text to a part of the rectangle.
|
||||||
/// Give a position within the rect, specified by the aligns
|
/// Give a position within the rect, specified by the aligns
|
||||||
pub fn align_rect(rect: Rect, align: (Align, Align)) -> Rect {
|
pub(crate) fn align_rect(rect: Rect, align: (Align, Align)) -> Rect {
|
||||||
let x = match align.0 {
|
let x = match align.0 {
|
||||||
Align::Min => rect.left(),
|
Align::Min => rect.left(),
|
||||||
Align::Center => rect.left() - 0.5 * rect.width(),
|
Align::Center => rect.left() - 0.5 * rect.width(),
|
||||||
|
@ -55,6 +55,7 @@ pub fn align_rect(rect: Rect, align: (Align, Align)) -> Rect {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// The layout of a `Ui`, e.g. horizontal left-aligned.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
// #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
// #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
|
@ -146,7 +147,7 @@ impl Layout {
|
||||||
/// Reserve this much space and move the cursor.
|
/// Reserve this much space and move the cursor.
|
||||||
/// Returns where to put the widget.
|
/// Returns where to put the widget.
|
||||||
///
|
///
|
||||||
/// # How sizes are negotiated
|
/// ## How sizes are negotiated
|
||||||
/// Each widget should have a *minimum desired size* and a *desired size*.
|
/// Each widget should have a *minimum desired size* and a *desired size*.
|
||||||
/// When asking for space, ask AT LEAST for you minimum, and don't ask for more than you need.
|
/// When asking for space, ask AT LEAST for you minimum, and don't ask for more than you need.
|
||||||
/// If you want to fill the space, ask about `available().size()` and use that.
|
/// If you want to fill the space, ask about `available().size()` and use that.
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub use {
|
||||||
math::*,
|
math::*,
|
||||||
memory::Memory,
|
memory::Memory,
|
||||||
movement_tracker::MovementTracker,
|
movement_tracker::MovementTracker,
|
||||||
paint::{color, Color, TextStyle, Texture},
|
paint::{color, Color, PaintJobs, TextStyle, Texture},
|
||||||
style::Style,
|
style::Style,
|
||||||
types::*,
|
types::*,
|
||||||
ui::Ui,
|
ui::Ui,
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, RangeInclusive, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, RangeInclusive, Sub, SubAssign};
|
||||||
|
|
||||||
|
/// A size or direction in 2D space.
|
||||||
|
///
|
||||||
|
/// Normally given in points, e.g. logical pixels.
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Vec2 {
|
pub struct Vec2 {
|
||||||
|
@ -220,7 +223,10 @@ impl std::fmt::Debug for Vec2 {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Sometimes called a Point. I prefer the shorter Pos2 so it is equal length to Vec2
|
// Sometimes called a Point. I prefer the shorter Pos2 so it is equal length to Vec2
|
||||||
|
/// A position on screen.
|
||||||
|
///
|
||||||
|
/// Normally given in points, e.g. logical pixels.
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Pos2 {
|
pub struct Pos2 {
|
||||||
|
@ -353,6 +359,9 @@ impl std::fmt::Debug for Pos2 {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// A rectangular region of space.
|
||||||
|
///
|
||||||
|
/// Normally given in points, e.g. logical pixels.
|
||||||
#[derive(Clone, Copy, Default, Eq, PartialEq)]
|
#[derive(Clone, Copy, Default, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Rect {
|
pub struct Rect {
|
||||||
|
@ -594,6 +603,11 @@ pub fn ease_in_ease_out(t: f32) -> f32 {
|
||||||
3.0 * t * t - 2.0 * t * t * t
|
3.0 * t * t - 2.0 * t * t * t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The circumference of a circle divided by its radius.
|
||||||
|
///
|
||||||
|
/// Represents one turn in radian angles. Equal to `2 * pi`.
|
||||||
|
///
|
||||||
|
/// See https://tauday.com/
|
||||||
pub const TAU: f32 = 2.0 * std::f32::consts::PI;
|
pub const TAU: f32 = 2.0 * std::f32::consts::PI;
|
||||||
|
|
||||||
pub fn round_to_precision(value: f32, precision: usize) -> f32 {
|
pub fn round_to_precision(value: f32, precision: usize) -> f32 {
|
||||||
|
|
|
@ -6,6 +6,12 @@ use crate::{
|
||||||
Id, Layer, Pos2, Rect,
|
Id, Layer, Pos2, Rect,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The data that Egui persists between frames.
|
||||||
|
///
|
||||||
|
/// This includes window positions and sizes,
|
||||||
|
/// how far the user has scrolled in a `ScrollArea` etc.
|
||||||
|
///
|
||||||
|
/// If you want this to persist when closing your app you should serialize `Memory` and store it.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "with_serde", serde(default))]
|
#[cfg_attr(feature = "with_serde", serde(default))]
|
||||||
|
@ -30,7 +36,7 @@ pub struct Memory {
|
||||||
pub(crate) areas: Areas,
|
pub(crate) areas: Areas,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Say there is a butotn in a scroll area.
|
/// Say there is a button in a scroll area.
|
||||||
/// If the user clicks the button, the button should click.
|
/// If the user clicks the button, the button should click.
|
||||||
/// If the user drags the button we should scroll the scroll area.
|
/// If the user drags the button we should scroll the scroll area.
|
||||||
/// So what we do is that when the mouse is pressed we register both the button
|
/// So what we do is that when the mouse is pressed we register both the button
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/// 0-255 `sRGBA`. TODO: rename `sRGBA` for clarity.
|
// TODO: rename `Color` to `sRGBA` for clarity.
|
||||||
/// Uses premultiplied alpha.
|
/// 0-255 `sRGBA`. Uses premultiplied alpha.
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Color {
|
pub struct Color {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use super::{
|
||||||
texture_atlas::{Texture, TextureAtlas},
|
texture_atlas::{Texture, TextureAtlas},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// TODO: rename
|
// TODO: rename
|
||||||
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
// #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
// #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub enum TextStyle {
|
pub enum TextStyle {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
/// An 8-bit texture containing font data.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
/// e.g. a hash of the data. Use this to detect changes!
|
/// e.g. a hash of the data. Use this to detect changes!
|
||||||
pub id: u64, // TODO
|
pub id: u64,
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
pub pixels: Vec<u8>,
|
pub pixels: Vec<u8>,
|
||||||
|
@ -25,7 +26,9 @@ impl std::ops::IndexMut<(usize, usize)> for Texture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A texture pixels, used for fonts.
|
/// Contains font data in an atlas, where each character occupied a small rectangle.
|
||||||
|
///
|
||||||
|
/// More characters can be added, possibly expanding the texture.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct TextureAtlas {
|
pub struct TextureAtlas {
|
||||||
texture: Texture,
|
texture: Texture,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use crate::{color::*, math::*, paint::LineStyle, types::*};
|
use crate::{color::*, math::*, paint::LineStyle, types::*};
|
||||||
|
|
||||||
// TODO: split into Spacing and Style?
|
// TODO: split into Spacing and Style?
|
||||||
|
/// Specifies the look and feel of a `Ui`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Style {
|
pub struct Style {
|
||||||
|
|
|
@ -4,9 +4,12 @@ use crate::{math::Rect, Context, Ui};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// What Egui emits each frame.
|
||||||
|
/// The backend should use this.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
// #[cfg_attr(feature = "with_serde", derive(serde::Serialize))]
|
// #[cfg_attr(feature = "with_serde", derive(serde::Serialize))]
|
||||||
pub struct Output {
|
pub struct Output {
|
||||||
|
/// Set the cursor to this icon.
|
||||||
pub cursor_icon: CursorIcon,
|
pub cursor_icon: CursorIcon,
|
||||||
|
|
||||||
/// If set, open this url.
|
/// If set, open this url.
|
||||||
|
@ -43,6 +46,9 @@ impl Default for CursorIcon {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// The result of an interaction.
|
||||||
|
///
|
||||||
|
/// For instance, this lets you know whether or not a widget has been clicked this frame.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
// #[cfg_attr(feature = "with_serde", derive(serde::Serialize))]
|
// #[cfg_attr(feature = "with_serde", derive(serde::Serialize))]
|
||||||
pub struct InteractInfo {
|
pub struct InteractInfo {
|
||||||
|
@ -90,7 +96,10 @@ impl InteractInfo {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// TODO: rename GuiResponse
|
/// The result of adding a widget to an `Ui`.
|
||||||
|
///
|
||||||
|
/// This lets you know whether or not a widget has been clicked this frame.
|
||||||
|
/// It also lets you easily show a tooltip on hover.
|
||||||
pub struct GuiResponse {
|
pub struct GuiResponse {
|
||||||
/// The senses (click or drag) that the widget is interested in (if any).
|
/// The senses (click or drag) that the widget is interested in (if any).
|
||||||
pub sense: Sense,
|
pub sense: Sense,
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl Ui {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Options for this ui, and any child uis we may spawn.
|
/// Style options for this `Ui` and its children.
|
||||||
pub fn style(&self) -> &Style {
|
pub fn style(&self) -> &Style {
|
||||||
&self.style
|
&self.style
|
||||||
}
|
}
|
||||||
|
@ -279,9 +279,10 @@ impl Ui {
|
||||||
pub fn request_kb_focus(&self, id: Id) {
|
pub fn request_kb_focus(&self, id: Id) {
|
||||||
self.memory().kb_focus_id = Some(id);
|
self.memory().kb_focus_id = Some(id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
/// # `Id` creation
|
||||||
|
impl Ui {
|
||||||
/// Will warn if the returned id is not guaranteed unique.
|
/// Will warn if the returned id is not guaranteed unique.
|
||||||
/// Use this to generate widget ids for widgets that have persistent state in Memory.
|
/// Use this to generate widget ids for widgets that have persistent state in Memory.
|
||||||
/// If the `id_source` is not unique within this ui
|
/// If the `id_source` is not unique within this ui
|
||||||
|
@ -328,10 +329,10 @@ impl Ui {
|
||||||
pub fn make_child_id(&self, id_seed: impl Hash) -> Id {
|
pub fn make_child_id(&self, id_seed: impl Hash) -> Id {
|
||||||
self.id.with(id_seed)
|
self.id.with(id_seed)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
/// # Interaction
|
||||||
// Interaction
|
impl Ui {
|
||||||
|
|
||||||
pub fn interact(&self, rect: Rect, id: Id, sense: Sense) -> InteractInfo {
|
pub fn interact(&self, rect: Rect, id: Id, sense: Sense) -> InteractInfo {
|
||||||
self.ctx
|
self.ctx
|
||||||
.interact(self.layer, self.clip_rect, rect, Some(id), sense)
|
.interact(self.layer, self.clip_rect, rect, Some(id), sense)
|
||||||
|
@ -374,7 +375,7 @@ impl Ui {
|
||||||
/// Reserve this much space and move the cursor.
|
/// Reserve this much space and move the cursor.
|
||||||
/// Returns where to put the widget.
|
/// Returns where to put the widget.
|
||||||
///
|
///
|
||||||
/// # How sizes are negotiated
|
/// ## How sizes are negotiated
|
||||||
/// Each widget should have a *minimum desired size* and a *desired size*.
|
/// Each widget should have a *minimum desired size* and a *desired size*.
|
||||||
/// When asking for space, ask AT LEAST for you minimum, and don't ask for more than you need.
|
/// When asking for space, ask AT LEAST for you minimum, and don't ask for more than you need.
|
||||||
/// If you want to fill the space, ask about `available().size()` and use that.
|
/// If you want to fill the space, ask about `available().size()` and use that.
|
||||||
|
@ -434,10 +435,10 @@ impl Ui {
|
||||||
self.child_count += 1;
|
self.child_count += 1;
|
||||||
child_rect
|
child_rect
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------
|
/// # Painting related stuff
|
||||||
// Painting related stuff
|
impl Ui {
|
||||||
|
|
||||||
/// It is up to the caller to make sure there is room for this.
|
/// It is up to the caller to make sure there is room for this.
|
||||||
/// Can be used for free painting.
|
/// Can be used for free painting.
|
||||||
/// NOTE: all coordinates are screen coordinates!
|
/// NOTE: all coordinates are screen coordinates!
|
||||||
|
@ -524,39 +525,44 @@ impl Ui {
|
||||||
color,
|
color,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
/// # Adding widgets
|
||||||
// Addding Widgets
|
impl Ui {
|
||||||
|
|
||||||
pub fn add(&mut self, widget: impl Widget) -> GuiResponse {
|
pub fn add(&mut self, widget: impl Widget) -> GuiResponse {
|
||||||
let interact = widget.ui(self);
|
let interact = widget.ui(self);
|
||||||
self.response(interact)
|
self.response(interact)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience functions:
|
/// Shortcut for `add(Label::new(text))`
|
||||||
|
|
||||||
pub fn label(&mut self, label: impl Into<Label>) -> GuiResponse {
|
pub fn label(&mut self, label: impl Into<Label>) -> GuiResponse {
|
||||||
self.add(label.into())
|
self.add(label.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shortcut for `add(Hyperlink::new(url))`
|
||||||
pub fn hyperlink(&mut self, url: impl Into<String>) -> GuiResponse {
|
pub fn hyperlink(&mut self, url: impl Into<String>) -> GuiResponse {
|
||||||
self.add(Hyperlink::new(url))
|
self.add(Hyperlink::new(url))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shortcut for `add(Button::new(text))`
|
||||||
pub fn button(&mut self, text: impl Into<String>) -> GuiResponse {
|
pub fn button(&mut self, text: impl Into<String>) -> GuiResponse {
|
||||||
self.add(Button::new(text))
|
self.add(Button::new(text))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Argument order matching that of Dear ImGui
|
// Argument order matching that of Dear ImGui
|
||||||
|
/// Show a checkbox.
|
||||||
pub fn checkbox(&mut self, text: impl Into<String>, checked: &mut bool) -> GuiResponse {
|
pub fn checkbox(&mut self, text: impl Into<String>, checked: &mut bool) -> GuiResponse {
|
||||||
self.add(Checkbox::new(checked, text))
|
self.add(Checkbox::new(checked, text))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Argument order matching that of Dear ImGui
|
// Argument order matching that of Dear ImGui
|
||||||
|
/// Show a radio button.
|
||||||
pub fn radio(&mut self, text: impl Into<String>, checked: bool) -> GuiResponse {
|
pub fn radio(&mut self, text: impl Into<String>, checked: bool) -> GuiResponse {
|
||||||
self.add(RadioButton::new(checked, text))
|
self.add(RadioButton::new(checked, text))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Show a radio button. It is selected if `*curr_value == radio_value`.
|
||||||
|
/// If clicked, `radio_value` is assigned to `*curr_value`;
|
||||||
pub fn radio_value<Value: PartialEq>(
|
pub fn radio_value<Value: PartialEq>(
|
||||||
&mut self,
|
&mut self,
|
||||||
text: impl Into<String>,
|
text: impl Into<String>,
|
||||||
|
@ -570,13 +576,14 @@ impl Ui {
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shortcut for `add(Separator::new())`
|
||||||
pub fn separator(&mut self) -> GuiResponse {
|
pub fn separator(&mut self) -> GuiResponse {
|
||||||
self.add(Separator::new())
|
self.add(Separator::new())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
/// # Addding Containers / Sub-uis:
|
||||||
// Addding Containers / Sub-uis:
|
impl Ui {
|
||||||
|
|
||||||
pub fn collapsing<R>(
|
pub fn collapsing<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
text: impl Into<String>,
|
text: impl Into<String>,
|
||||||
|
@ -737,6 +744,4 @@ impl Ui {
|
||||||
self.allocate_space(size);
|
self.allocate_space(size);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
|
//! Example widget uses:
|
||||||
|
//!
|
||||||
|
//! * `ui.add(Label::new("Text").text_color(color::red));`
|
||||||
|
//!
|
||||||
|
//! * `if ui.add(Button::new("Click me")).clicked { ... }`
|
||||||
|
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
use crate::{layout::Direction, *};
|
use crate::{layout::Direction, *};
|
||||||
|
|
||||||
mod slider;
|
mod slider;
|
||||||
pub mod text_edit;
|
pub(crate) mod text_edit;
|
||||||
|
|
||||||
pub use {paint::*, slider::*, text_edit::*};
|
pub use {slider::*, text_edit::*};
|
||||||
|
|
||||||
|
use paint::*;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -98,7 +106,9 @@ impl Label {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Usage: label!("Foo: {}", bar)
|
/// Shortcut for creating a `Label` widget.
|
||||||
|
///
|
||||||
|
/// Usage: `label!("Foo: {}", bar)` equivalent to `Label::new(format!("Foo: {}", bar))`.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! label {
|
macro_rules! label {
|
||||||
($fmt:expr) => ($crate::widgets::Label::new($fmt));
|
($fmt:expr) => ($crate::widgets::Label::new($fmt));
|
||||||
|
@ -382,10 +392,6 @@ impl RadioButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn radio(checked: bool, text: impl Into<String>) -> RadioButton {
|
|
||||||
RadioButton::new(checked, text)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Widget for RadioButton {
|
impl Widget for RadioButton {
|
||||||
fn ui(self, ui: &mut Ui) -> InteractInfo {
|
fn ui(self, ui: &mut Ui) -> InteractInfo {
|
||||||
let RadioButton {
|
let RadioButton {
|
||||||
|
|
Loading…
Reference in a new issue