Add a lot of documentation and inter-doc links

This commit is contained in:
Emil Ernerfeldt 2020-12-27 12:57:15 +01:00
parent 22e442c613
commit a1fa9903b0
29 changed files with 226 additions and 138 deletions

View file

@ -174,7 +174,7 @@ loop {
egui_ctx.begin_frame(raw_input);
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
let (output, paint_commands) = egui_ctx.end_frame();
let paint_jobs = self.ctx.tesselate(paint_commands); // create triangles to paint
let paint_jobs = egui_ctx.tesselate(paint_commands); // create triangles to paint
my_integration.paint(paint_jobs);
my_integration.set_cursor_icon(output.cursor_icon);
// Also see `egui::Output` for more

View file

@ -1,3 +1,5 @@
//! One- and two-dimensional alignment ([`Align::Center`], [`LEFT_TOP`] etc).
use crate::math::{pos2, Rect};
/// left/center/right or top/center/bottom alignment for e.g. anchors and `Layout`s.
@ -5,27 +7,30 @@ use crate::math::{pos2, Rect};
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Align {
/// Left/Top
/// Left or top.
Min,
/// Note: requires a bounded/known available_width.
/// Horizontal or vertical center.
Center,
/// Right/Bottom
/// Note: requires a bounded/known available_width.
/// Right or bottom.
Max,
}
impl Align {
/// Convenience for [`Self::Min`]
pub fn left() -> Self {
Self::Min
}
/// Convenience for [`Self::Max`]
pub fn right() -> Self {
Self::Max
}
/// Convenience for [`Self::Min`]
pub fn top() -> Self {
Self::Min
}
/// Convenience for [`Self::Max`]
pub fn bottom() -> Self {
Self::Max
}

View file

@ -29,7 +29,17 @@ impl State {
/// An area on the screen that can be moved by dragging.
///
/// This forms the base of the `Window` container.
/// This forms the base of the [`Window`] container.
///
/// ```
/// # let mut ctx = egui::CtxRef::default();
/// # ctx.begin_frame(Default::default());
/// # let ctx = &ctx;
/// egui::Area::new("my_area")
/// .fixed_pos(egui::pos2(32.0, 32.0))
/// .show(ctx, |ui| {
/// ui.label("Floating text!");
/// });
#[derive(Clone, Copy, Debug)]
pub struct Area {
id: Id,

View file

@ -1,6 +1,6 @@
//! Containers are pieces of the UI which wraps other pieces of UI. Examples: `Window`, `ScrollArea`, `Resize`, etc.
//! Containers are pieces of the UI which wraps other pieces of UI. Examples: [`Window`], [`ScrollArea`], [`Resize`], etc.
//!
//! For instance, a `Frame` adds a frame and background to some contained UI.
//! For instance, a [`Frame`] adds a frame and background to some contained UI.
pub(crate) mod area;
pub(crate) mod collapsing_header;

View file

@ -8,7 +8,16 @@ use crate::*;
/// A panel that covers the entire left side of the screen.
///
/// Panels should be added before adding any `Window`s.
/// `SidePanel`s should be added before adding any [`Window`]s.
///
/// ```
/// # let mut ctx = egui::CtxRef::default();
/// # ctx.begin_frame(Default::default());
/// # let ctx = &ctx;
/// egui::SidePanel::left("my_side_panel", 0.0).show(ctx, |ui| {
/// ui.label("Hello World!");
/// });
/// ```
pub struct SidePanel {
id: Id,
max_width: f32,
@ -56,7 +65,16 @@ impl SidePanel {
/// A panel that covers the entire top side of the screen.
///
/// Panels should be added before adding any `Window`s.
/// `TopPanel`s should be added before adding any [`Window`]s.
///
/// ```
/// # let mut ctx = egui::CtxRef::default();
/// # ctx.begin_frame(Default::default());
/// # let ctx = &ctx;
/// egui::TopPanel::top("my_top_panel").show(ctx, |ui| {
/// ui.label("Hello World!");
/// });
/// ```
pub struct TopPanel {
id: Id,
max_height: Option<f32>,
@ -108,7 +126,16 @@ impl TopPanel {
/// i.e. whatever area is left after adding other panels.
///
/// `CentralPanel` should be added after all other panels.
/// Any `Window`s and `Area`s will cover the `CentralPanel`.
/// Any [`Window`]s and [`Area`]s will cover the `CentralPanel`.
///
/// ```
/// # let mut ctx = egui::CtxRef::default();
/// # ctx.begin_frame(Default::default());
/// # let ctx = &ctx;
/// egui::CentralPanel::default().show(ctx, |ui| {
/// ui.label("Hello World!");
/// });
/// ```
#[derive(Default)]
pub struct CentralPanel {}

View file

@ -12,6 +12,14 @@ use super::*;
/// * if the window has a scroll area (off by default)
/// * if the window can be collapsed (minimized) to just the title bar (yes, by default)
/// * if there should be a close button (none by default)
///
/// ```
/// # let mut ctx = egui::CtxRef::default();
/// # ctx.begin_frame(Default::default());
/// # let ctx = &ctx;
/// egui::Window::new("My Window").show(ctx, |ui| {
/// ui.label("Hello World!");
/// });
pub struct Window<'open> {
title_label: Label,
open: Option<&'open mut bool>,
@ -24,7 +32,7 @@ pub struct Window<'open> {
}
impl<'open> Window<'open> {
/// The window title is used as a unique Id and must be unique, and should not change.
/// The window title is used as a unique [`Id`] and must be unique, and should not change.
/// This is true even if you disable the title bar with `.title_bar(false)`.
pub fn new(title: impl Into<String>) -> Self {
let title = title.into();

View file

@ -64,7 +64,7 @@ impl FrameState {
pub fn available_rect(&self) -> Rect {
debug_assert!(
self.available_rect.is_finite(),
"Called `available_rect()` before `begin_frame()`"
"Called `available_rect()` before `CtxRef::begin_frame()`"
);
self.available_rect
}
@ -101,8 +101,8 @@ impl FrameState {
// ----------------------------------------------------------------------------
/// A wrapper around `CtxRef`.
/// This is how you will normally access a [`Context`].
/// A wrapper around [`Arc`](std::sync::Arc)`<`[`Context`]`>`.
/// This is how you will normally create and access a [`Context`].
#[derive(Clone)]
pub struct CtxRef(std::sync::Arc<Context>);
@ -145,7 +145,7 @@ impl Default for CtxRef {
impl CtxRef {
/// Call at the start of every frame.
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
/// Put your widgets into a [`SidePanel`], [`TopPanel`], [`CentralPanel`], [`Window`] or [`Area`].
pub fn begin_frame(&mut self, new_input: RawInput) {
let mut self_: Context = (*self.0).clone();
self_.begin_frame_mut(new_input);
@ -154,8 +154,8 @@ impl CtxRef {
// ---------------------------------------------------------------------
/// If the given `Id` is not unique, an error will be printed at the given position.
/// Call this for `Id`:s that need interaction or persistence.
/// If the given [`Id`] is not unique, an error will be printed at the given position.
/// Call this for [`Id`]:s that need interaction or persistence.
pub(crate) fn register_interaction_id(&self, id: Id, new_pos: Pos2) {
let prev_pos = self.memory().used_ids.insert(id, new_pos);
if let Some(prev_pos) = prev_pos {
@ -352,12 +352,9 @@ impl CtxRef {
// ----------------------------------------------------------------------------
/// Thi is the first thing you need when working with Egui.
/// This is the first thing you need when working with Egui. Create using [`CtxRef`].
///
/// Contains the input state, memory, options and output.
/// `Ui`:s keep an `Arc` pointer to this.
/// This allows us to create several child `Ui`:s at once,
/// all working against the same shared Context.
/// Contains the [`InputState`], [`Memory`], [`Output`], options and more.
// TODO: too many mutexes. Maybe put it all behind one Mutex instead.
#[derive(Default)]
pub struct Context {
@ -442,17 +439,17 @@ impl Context {
&self.input
}
/// Not valid until first call to `begin_frame()`
/// Not valid until first call to [`CtxRef::begin_frame()`].
/// That's because since we don't know the proper `pixels_per_point` until then.
pub fn fonts(&self) -> &Fonts {
&*self
.fonts
.as_ref()
.expect("No fonts available until first call to Context::begin_frame()`")
.expect("No fonts available until first call to CtxRef::begin_frame()")
}
/// The Egui texture, containing font characters etc..
/// Not valid until first call to `begin_frame()`
/// The Egui texture, containing font characters etc.
/// Not valid until first call to [`CtxRef::begin_frame()`].
/// That's because since we don't know the proper `pixels_per_point` until then.
pub fn texture(&self) -> Arc<paint::Texture> {
self.fonts().texture()
@ -464,14 +461,17 @@ impl Context {
self.options.lock().font_definitions = font_definitions;
}
/// The [`Style`] used by all new windows, panels etc.
pub fn style(&self) -> Arc<Style> {
self.options.lock().style.clone()
}
/// The [`Style`] used by all new windows, panels etc.
pub fn set_style(&self, style: impl Into<Arc<Style>>) {
self.options.lock().style = style.into();
}
/// The number of physical pixels for each logical point.
pub fn pixels_per_point(&self) -> f32 {
self.input.pixels_per_point()
}
@ -643,22 +643,21 @@ impl Context {
}
/// True if Egui is currently interested in the mouse.
/// Could be the mouse is hovering over a Egui window,
/// or the user is dragging an Egui widget.
/// If false, the mouse is outside of any Egui area and so
/// Could be the mouse is hovering over a [`Window`] or the user is dragging a widget.
/// If `false`, the mouse is outside of any Egui area and so
/// you may be interested in what it is doing (e.g. controlling your game).
/// Returns `false` if a drag starts outside of Egui and then moves over an Egui window.
/// Returns `false` if a drag started outside of Egui and then moved over an Egui area.
pub fn wants_mouse_input(&self) -> bool {
self.is_using_mouse() || (self.is_mouse_over_area() && !self.input().mouse.down)
}
/// Is Egui currently using the mouse position (e.g. dragging a slider).
/// NOTE: this will return false if the mouse is just hovering over an Egui window.
/// NOTE: this will return `false` if the mouse is just hovering over an Egui area.
pub fn is_using_mouse(&self) -> bool {
self.memory().interaction.is_using_mouse()
}
/// If true, Egui is currently listening on text input (e.g. typing text in a `TextEdit`).
/// If `true`, Egui is currently listening on text input (e.g. typing text in a [`TextEdit`]).
pub fn wants_keyboard_input(&self) -> bool {
self.memory().interaction.kb_focus_id.is_some()
}
@ -687,7 +686,7 @@ impl Context {
/// Calling this with `value = true` will always yield a number larger than zero, quickly going towards one.
/// Calling this with `value = false` will always yield a number less than one, quickly going towards zero.
///
/// The function will call `request_repaint()` when appropriate.
/// The function will call [`Self::request_repaint()`] when appropriate.
pub fn animate_bool(&self, id: Id, value: bool) -> f32 {
let animation_time = self.style().animation_time;
let animated_value =

View file

@ -59,7 +59,8 @@ pub fn warn_if_debug_build(ui: &mut crate::Ui) {
// ----------------------------------------------------------------------------
/// Create a `Hyperlink` to this file (and line) on Github
/// Create a [`Hyperlink`](crate::Hyperlink) to this file (and line) on Github
///
/// Example: `ui.add(github_link_file_line!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export]
macro_rules! github_link_file_line {
@ -69,7 +70,8 @@ macro_rules! github_link_file_line {
}};
}
/// Create a `Hyperlink` to this file on github.
/// Create a [`Hyperlink`](crate::Hyperlink) to this file on github.
///
/// Example: `ui.add(github_link_file!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export]
macro_rules! github_link_file {
@ -79,7 +81,7 @@ macro_rules! github_link_file {
}};
}
/// Create a `Hyperlink` to this egui source code file on github.
/// Create a [`Hyperlink`](crate::Hyperlink) to this egui source code file on github.
#[doc(hidden)]
#[macro_export]
macro_rules! __egui_github_link_file {
@ -91,7 +93,7 @@ macro_rules! __egui_github_link_file {
};
}
/// Create a `Hyperlink` to this egui source code file and line on github.
/// Create a [`Hyperlink`](crate::Hyperlink) to this egui source code file and line on github.
#[doc(hidden)]
#[macro_export]
macro_rules! __egui_github_link_file_line {

View file

@ -7,7 +7,7 @@ const MAX_CLICK_DIST: f32 = 6.0;
/// The new mouse press must come within this many seconds from previous mouse release
const MAX_CLICK_DELAY: f64 = 0.3;
/// What the backend provides to Egui at the start of each frame.
/// What the integrations provides to Egui at the start of each frame.
///
/// Set the values that make sense, leave the rest at their `Default::default()`.
///
@ -94,7 +94,7 @@ impl RawInput {
}
}
/// What egui maintains
/// Input state that Egui updates each frame.
#[derive(Clone, Debug)]
pub struct InputState {
/// The raw input we got this frame
@ -146,7 +146,7 @@ impl Default for InputState {
}
}
/// What egui maintains
/// Mouse (or touch) state.
#[derive(Clone, Debug)]
pub struct MouseInput {
/// Is the button currently down?
@ -212,13 +212,18 @@ impl Default for MouseInput {
}
}
/// An input event. Only covers events used by Egui.
/// An input event generated by the integration.
///
/// This only covers events that Egui cares about.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Event {
/// The integration detected a "copy" event (e.g. Cmd+C).
Copy,
/// The integration detected a "cut" event (e.g. Cmd+X).
Cut,
/// Text input, e.g. via keyboard or paste action.
/// Do not pass '\n', '\r' here, but send `Key::Enter` instead.
///
/// When the user presses enter/return, do not send a `Text` (just [`Key::Enter`]).
Text(String),
Key {
key: Key,

View file

@ -38,7 +38,7 @@ impl Order {
}
/// An identifier for a paint layer.
/// Also acts as an identifier for `Area`:s.
/// Also acts as an identifier for [`Area`]:s.
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct LayerId {
@ -70,11 +70,11 @@ impl LayerId {
}
}
/// A unique identifier of a specific `PaintCmd` in a `PaintList`.
/// A unique identifier of a specific [`PaintCmd`] in a [`PaintList`].
#[derive(Clone, Copy, PartialEq)]
pub struct PaintCmdIdx(usize);
/// Each `PaintCmd` is paired with a clip rectangle.
/// A list of [`PaintCmd`]s paired with a clip rectangle.
#[derive(Clone, Default)]
pub struct PaintList(Vec<(Rect, PaintCmd)>);

View file

@ -2,8 +2,8 @@ use crate::{math::*, Align};
// ----------------------------------------------------------------------------
/// This describes the bounds and existing contents of an `Ui`.
/// It is what is used and updated by `Layout` when adding new widgets.
/// This describes the bounds and existing contents of an [`Ui`][`crate::Ui`].
/// It is what is used and updated by [`Layout`] when adding new widgets.
#[derive(Clone, Copy, Debug)]
pub struct Region {
/// This is the minimal size of the `Ui`.
@ -64,7 +64,7 @@ impl Region {
// ----------------------------------------------------------------------------
/// Main layout direction
/// Layout direction, one of `LeftToRight`, `RightToLeft`, `TopDown`, `BottomUp`.
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
@ -93,7 +93,7 @@ impl Direction {
// ----------------------------------------------------------------------------
/// The layout of a `Ui`, e.g. horizontal left-aligned.
/// The layout of a [`Ui`][`crate::Ui`], e.g. "vertical & centered".
#[derive(Clone, Copy, Debug, PartialEq)]
// #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Layout {

View file

@ -3,9 +3,9 @@
//! To get started with Egui, you can use one of the available integrations
//! such as [`egui_web`](https://crates.io/crates/egui_web) or [`egui_glium`](https://crates.io/crates/egui_glium).
//!
//! Whatever you use, you need an `egui::Context` (by convention referred to by `ctx`).
//! With it you can then get access to an `Ui` where you can put widgets.
//! Use one of `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. For instace:
//! Whatever you use, you need an [`CtxRef`] (by convention referred to by `ctx`).
//! Use one of [`SidePanel`], [`TopPanel`], [`CentralPanel`], [`Window`] or [`Area`] to
//! get access to an [`Ui`] where you can put widgets. For example:
//!
//! ```
//! # let mut ctx = egui::CtxRef::default();
@ -27,7 +27,7 @@
//! egui_ctx.begin_frame(raw_input);
//! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here
//! let (output, paint_commands) = egui_ctx.end_frame();
//! let paint_jobs = self.ctx.tesselate(paint_commands); // create triangles to paint
//! let paint_jobs = egui_ctx.tesselate(paint_commands); // create triangles to paint
//! my_integration.paint(paint_jobs);
//! my_integration.set_cursor_icon(output.cursor_icon);
//! // Also see `egui::Output` for more
@ -56,6 +56,8 @@
clippy::match_wildcard_for_single_variants,
clippy::mem_forget,
clippy::mismatched_target_os,
clippy::missing_errors_doc,
clippy::missing_safety_doc,
clippy::needless_borrow,
clippy::needless_continue,
clippy::needless_pass_by_value,
@ -67,8 +69,12 @@
clippy::unnested_or_patterns,
clippy::verbose_file_reads,
future_incompatible,
missing_crate_level_docs,
missing_doc_code_examples,
// missing_docs,
nonstandard_style,
rust_2018_idioms
rust_2018_idioms,
unused_doc_comments,
)]
pub mod align;

View file

@ -1,4 +1,8 @@
//! Vectors, positions, rectangles etc.
//!
//! Conventions (unless otherwise specified):
//! * All angles are in radians
//! * All metrics are in points (logical pixels)
use std::ops::{Add, Div, Mul, RangeInclusive, Sub};
@ -14,6 +18,7 @@ pub use {pos2::*, rect::*, rot2::*, vec2::*};
// ----------------------------------------------------------------------------
/// Helper trait to implement [`lerp`] and [`remap`].
pub trait One {
fn one() -> Self;
}
@ -28,6 +33,7 @@ impl One for f64 {
}
}
/// Helper trait to implement [`lerp`] and [`remap`].
pub trait Real:
Copy
+ PartialEq
@ -151,7 +157,8 @@ pub(crate) fn format_with_decimals_in_range(
}
}
/// Should return true when arguments are the same within some rounding error.
/// Return true when arguments are the same within some rounding error.
///
/// For instance `almost_equal(x, x.to_degrees().to_radians(), f32::EPSILON)` should hold true for all x.
/// The `epsilon` can be `f32::EPSILON` to handle simple transforms (like degrees -> radians)
/// but should be higher to handle more complex transformations.
@ -223,6 +230,7 @@ fn test_remap() {
// ----------------------------------------------------------------------------
/// Extends `f32`, `Vec2` etc with `at_least` and `at_most` as aliases for `max` and `min`.
pub trait NumExt {
/// More readable version of `self.max(lower_limit)`
fn at_least(self, lower_limit: Self) -> Self;
@ -231,62 +239,21 @@ pub trait NumExt {
fn at_most(self, upper_limit: Self) -> Self;
}
impl NumExt for f32 {
/// More readable version of `self.max(lower_limit)`
fn at_least(self, lower_limit: Self) -> Self {
self.max(lower_limit)
}
/// More readable version of `self.min(upper_limit)`
fn at_most(self, upper_limit: Self) -> Self {
self.min(upper_limit)
}
macro_rules! impl_num_ext {
($t: ty) => {
impl NumExt for $t {
fn at_least(self, lower_limit: Self) -> Self {
self.max(lower_limit)
}
fn at_most(self, upper_limit: Self) -> Self {
self.min(upper_limit)
}
}
};
}
impl NumExt for f64 {
/// More readable version of `self.max(lower_limit)`
fn at_least(self, lower_limit: Self) -> Self {
self.max(lower_limit)
}
/// More readable version of `self.min(upper_limit)`
fn at_most(self, upper_limit: Self) -> Self {
self.min(upper_limit)
}
}
impl NumExt for usize {
/// More readable version of `self.max(lower_limit)`
fn at_least(self, lower_limit: Self) -> Self {
self.max(lower_limit)
}
/// More readable version of `self.min(upper_limit)`
fn at_most(self, upper_limit: Self) -> Self {
self.min(upper_limit)
}
}
impl NumExt for Vec2 {
/// More readable version of `self.max(lower_limit)`
fn at_least(self, lower_limit: Self) -> Self {
self.max(lower_limit)
}
/// More readable version of `self.min(upper_limit)`
fn at_most(self, upper_limit: Self) -> Self {
self.min(upper_limit)
}
}
impl NumExt for Pos2 {
/// More readable version of `self.max(lower_limit)`
fn at_least(self, lower_limit: Self) -> Self {
self.max(lower_limit)
}
/// More readable version of `self.min(upper_limit)`
fn at_most(self, upper_limit: Self) -> Self {
self.min(upper_limit)
}
}
impl_num_ext!(f32);
impl_num_ext!(f64);
impl_num_ext!(usize);
impl_num_ext!(Vec2);
impl_num_ext!(Pos2);

View file

@ -2,10 +2,12 @@ use std::ops::{Add, AddAssign, RangeInclusive, Sub, SubAssign};
use crate::math::*;
// 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.
/// Normally given in points (logical pixels).
///
/// Mathematically this is known as a "point", but the term position was chosen so not to
/// conflict with the unit (one point = X physical pixels).
#[derive(Clone, Copy, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Pos2 {
@ -14,6 +16,8 @@ pub struct Pos2 {
// implicit w = 1
}
/// `pos2(x,y) == Pos2::new(x, y)`
#[inline(always)]
pub const fn pos2(x: f32, y: f32) -> Pos2 {
Pos2 { x, y }
}
@ -35,6 +39,8 @@ impl Pos2 {
Self { x, y }
}
/// The vector from origin to this position.
/// `p.to_vec2()` is equivalent to `p - Pos2::default()`.
pub fn to_vec2(self) -> Vec2 {
Vec2 {
x: self.x,

View file

@ -8,7 +8,7 @@ use super::Vec2;
// `vec2(c,s)` represents where the X axis will end up after rotation.
//
/// Represents a rotation in the 2D plane.
/// A rotation of 90° rotates the X axis to the Y axis.
/// A rotation of 𝞃/4 = 90° rotates the X axis to the Y axis.
/// Normally a `Rot2` is normalized (unit-length).
/// If not, it will also scale vectors.
#[derive(Clone, Copy, PartialEq)]
@ -32,7 +32,7 @@ impl Rot2 {
Self { s: 0.0, c: 1.0 }
}
/// A `TAU / 4.0` rotation means rotating the X axis to the Y axis.
/// A 𝞃/4 = 90° rotation means rotating the X axis to the Y axis.
pub fn from_angle(angle: f32) -> Self {
let (s, c) = angle.sin_cos();
Self { s, c }

View file

@ -1,3 +1,5 @@
//! Find "simple" numbers is some range. Used by sliders.
#![allow(clippy::float_cmp)] // I know what I'm doing
const NUM_DECIMALS: usize = 15;

View file

@ -2,9 +2,12 @@ use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, RangeInclusive, Sub, Su
use crate::math::*;
/// A size or direction in 2D space.
/// A vector has a direction and length.
/// A [`Vec2`] is often used to represent a size.
///
/// Normally given in points, e.g. logical pixels.
/// Egui represents positions using [`Pos2`].
///
/// Normally the units are points (logical pixels).
#[derive(Clone, Copy, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Vec2 {
@ -12,6 +15,7 @@ pub struct Vec2 {
pub y: f32,
}
/// `vec2(x,y) == Vec2::new(x, y)`
#[inline(always)]
pub const fn vec2(x: f32, y: f32) -> Vec2 {
Vec2 { x, y }
@ -75,6 +79,9 @@ impl Vec2 {
self.x * self.x + self.y * self.y
}
/// Create a unit vector with the given angle (in radians).
/// * An angle of zero gives the unit X axis.
/// * An angle of 𝞃/4 = 90° gives the unit Y axis.
pub fn angled(angle: f32) -> Self {
vec2(angle.cos(), angle.sin())
}
@ -94,6 +101,7 @@ impl Vec2 {
vec2(self.x.ceil(), self.y.ceil())
}
/// True if all members are also finite.
pub fn is_finite(self) -> bool {
self.x.is_finite() && self.y.is_finite()
}

View file

@ -7,7 +7,7 @@ use {
},
};
// TODO: rename, e.g. `paint::Cmd`?
/// A paint primitive such as a circle or a piece of text.
#[derive(Clone, Debug)]
pub enum PaintCmd {
/// Paint nothing. This can be useful as a placeholder.

View file

@ -1,6 +1,4 @@
//! Graphics module.
//!
//! Handles fonts, textures, color, geometry and tesselation.
//! 2D graphics/rendering. Fonts, textures, color, geometry, tesselation etc.
pub mod color;
pub mod command;

View file

@ -8,6 +8,8 @@ use crate::{
};
/// Helper to paint shapes and text to a specific region on a specific layer.
///
/// All coordinates are screen coordinates in the unit points (one point can consist of many physical pixels).
#[derive(Clone)]
pub struct Painter {
/// Source of fonts and destination of paint commands

View file

@ -7,7 +7,7 @@ use crate::{
types::*,
};
/// Specifies the look and feel of a `Ui`.
/// Specifies the look and feel of a [`Ui`].
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Style {

View file

@ -22,6 +22,9 @@ pub struct Output {
pub needs_repaint: bool,
}
/// A mouse cursor icon.
///
/// Egui emits a `CursorIcond` in [`Output`] each frame as a request to the integration.
#[derive(Clone, Copy)]
// #[cfg_attr(feature = "serde", derive(serde::Serialize))]
// #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
@ -47,7 +50,7 @@ impl Default for CursorIcon {
// ----------------------------------------------------------------------------
/// The result of adding a widget to an `Ui`.
/// The result of adding a widget to a [`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.
@ -67,7 +70,7 @@ pub struct Response {
/// The area of the screen we are talking about.
pub rect: Rect,
/// The senses (click or drag) that the widget is interested in (if any).
/// The senses (click and/or drag) that the widget was interested in (if any).
pub sense: Sense,
// OUT:
@ -88,8 +91,17 @@ pub struct Response {
/// The widget had keyboard focus and lost it,
/// perhaps because the user pressed enter.
/// This is often a signal to the user to the application
/// to make use of the contents of the text field.
/// If you want to do an action when a user presses enter in a text field,
/// use this.
///
/// ```
/// # let mut ui = egui::Ui::__test();
/// # let mut my_text = String::new();
/// # fn do_request(_: &str) {}
/// if ui.text_edit_singleline(&mut my_text).lost_kb_focus {
/// do_request(&my_text);
/// }
/// ```
pub lost_kb_focus: bool,
}
@ -246,6 +258,7 @@ impl Sense {
Sense::hover()
}
/// Sense clicks and hover, but not drags.
pub fn click() -> Self {
Self {
click: true,
@ -253,6 +266,7 @@ impl Sense {
}
}
/// Sense drags and hover, but not clicks.
pub fn drag() -> Self {
Self {
click: false,
@ -260,7 +274,7 @@ impl Sense {
}
}
/// e.g. a slider or window
/// Sense both clicks, drags and hover (e.g. a slider or window).
pub fn click_and_drag() -> Self {
Self {
click: true,
@ -268,6 +282,7 @@ impl Sense {
}
}
/// The logical "or" of two `Sense`s.
#[must_use]
pub fn union(self, other: Self) -> Self {
Self {

View file

@ -4,8 +4,19 @@ use std::{hash::Hash, sync::Arc};
use crate::{color::*, containers::*, layout::*, mutex::MutexGuard, paint::*, widgets::*, *};
/// Represents a region of the screen
/// with a type of layout (horizontal or vertical).
/// This is what you use to place widgets.
///
/// Represents a region of the screen with a type of layout (horizontal or vertical).
///
/// ```
/// # let mut ui = egui::Ui::__test();
/// ui.add(egui::Label::new("Hello World!"));
/// ui.label("A shorter and more convenient way to add a label.");
/// ui.horizontal(|ui| {
/// ui.label("Add widgets");
/// ui.button("on the same row!");
/// });
/// ```
pub struct Ui {
/// ID of this ui.
/// Generated based on id of parent ui together with
@ -81,6 +92,7 @@ impl Ui {
// -------------------------------------------------
/// A unique identity of this `Ui`.
pub fn id(&self) -> Id {
self.id
}
@ -96,10 +108,12 @@ impl Ui {
Arc::make_mut(&mut self.style) // clone-on-write
}
/// Changes apply to this `Ui` and its subsequent children.
pub fn set_style(&mut self, style: impl Into<Arc<Style>>) {
self.style = style.into();
}
/// Get a reference to the parent [`CtxRef`].
pub fn ctx(&self) -> &CtxRef {
self.painter.ctx()
}
@ -588,6 +602,17 @@ impl Ui {
/// # Adding widgets
impl Ui {
/// Add a widget to this `Ui` at a location dependent on the current [`Layout`].
///
/// The returned [`Response`] can be used to check for interactions,
/// as well as adding tooltips using [`Response::on_hover_text`].
///
/// ```
/// # let mut ui = egui::Ui::__test();
/// # let mut my_value = 42;
/// let response = ui.add(egui::Slider::i32(&mut my_value, 0..=100));
/// response.on_hover_text("Drag me!");
/// ```
pub fn add(&mut self, widget: impl Widget) -> Response {
widget.ui(self)
}

View file

@ -1,4 +1,4 @@
//! Tools used by Egui, but that doesn't depend on anything in Egui.
//! Miscellaneous tools used by the rest of Egui.
pub(crate) mod cache;
mod history;

View file

@ -1,5 +1,6 @@
use crate::*;
/// A clickable image within a frame.
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
#[derive(Clone, Debug)]
pub struct ImageButton {

View file

@ -16,7 +16,7 @@ fn set(value_function: &mut GetSetValue<'_>, value: f64) {
(value_function)(Some(value));
}
/// A floating point value that you can change by dragging the number. More compact than a slider.
/// A numeric value that you can change by dragging the number. More compact than a [`Slider`].
pub struct DragValue<'a> {
value_function: GetSetValue<'a>,
speed: f32,

View file

@ -1,5 +1,6 @@
use crate::*;
/// An widget to show an image of a given size.
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
#[derive(Clone, Copy, Debug)]
pub struct Image {

View file

@ -1,4 +1,4 @@
//! Widgets are pieces of GUI such as labels, buttons, sliders etc.
//! Widgets are pieces of GUI such as [`Label`], [`Button`], [`Slider`] etc.
//!
//! Example widget uses:
//! * `ui.add(Label::new("Text").text_color(color::red));`
@ -21,9 +21,10 @@ use paint::*;
// ----------------------------------------------------------------------------
/// Anything implementing Widget can be added to a Ui with `Ui::add`
/// Anything implementing Widget can be added to a [`Ui`] with [`Ui::add`].
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub trait Widget {
/// Allocate space, interact, paint, and return a [`Response`].
fn ui(self, ui: &mut Ui) -> Response;
}
@ -627,7 +628,7 @@ impl Widget for RadioButton {
/// One out of several alternatives, either selected or not.
/// Will mark selected items with a different background color
/// An alternative to `RadioButton` and `Checkbox`.
/// An alternative to [`RadioButton`] and [`Checkbox`].
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
#[derive(Debug)]
pub struct SelectableLabel {
@ -690,7 +691,7 @@ impl Widget for SelectableLabel {
// ----------------------------------------------------------------------------
/// A visual separator. A horizontal or vertical line (depending on `Layout`).
/// A visual separator. A horizontal or vertical line (depending on [`Layout`]).
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct Separator {
spacing: f32,

View file

@ -162,7 +162,7 @@ impl<'a> Slider<'a> {
self
}
#[deprecated = "Use fixed_decimals instea"]
#[deprecated = "Use fixed_decimals instead"]
pub fn precision(self, precision: usize) -> Self {
self.max_decimals(precision)
}