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); egui_ctx.begin_frame(raw_input);
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
let (output, paint_commands) = egui_ctx.end_frame(); 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.paint(paint_jobs);
my_integration.set_cursor_icon(output.cursor_icon); my_integration.set_cursor_icon(output.cursor_icon);
// Also see `egui::Output` for more // 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}; use crate::math::{pos2, Rect};
/// left/center/right or top/center/bottom alignment for e.g. anchors and `Layout`s. /// 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", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Align { pub enum Align {
/// Left/Top /// Left or top.
Min, Min,
/// Note: requires a bounded/known available_width. /// Horizontal or vertical center.
Center, Center,
/// Right/Bottom /// Right or bottom.
/// Note: requires a bounded/known available_width.
Max, Max,
} }
impl Align { impl Align {
/// Convenience for [`Self::Min`]
pub fn left() -> Self { pub fn left() -> Self {
Self::Min Self::Min
} }
/// Convenience for [`Self::Max`]
pub fn right() -> Self { pub fn right() -> Self {
Self::Max Self::Max
} }
/// Convenience for [`Self::Min`]
pub fn top() -> Self { pub fn top() -> Self {
Self::Min Self::Min
} }
/// Convenience for [`Self::Max`]
pub fn bottom() -> Self { pub fn bottom() -> Self {
Self::Max Self::Max
} }

View file

@ -29,7 +29,17 @@ impl State {
/// An area on the screen that can be moved by dragging. /// 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)] #[derive(Clone, Copy, Debug)]
pub struct Area { pub struct Area {
id: Id, 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 area;
pub(crate) mod collapsing_header; pub(crate) mod collapsing_header;

View file

@ -8,7 +8,16 @@ use crate::*;
/// A panel that covers the entire left side of the screen. /// 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 { pub struct SidePanel {
id: Id, id: Id,
max_width: f32, max_width: f32,
@ -56,7 +65,16 @@ impl SidePanel {
/// A panel that covers the entire top side of the screen. /// 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 { pub struct TopPanel {
id: Id, id: Id,
max_height: Option<f32>, max_height: Option<f32>,
@ -108,7 +126,16 @@ impl TopPanel {
/// i.e. whatever area is left after adding other panels. /// i.e. whatever area is left after adding other panels.
/// ///
/// `CentralPanel` should be added after all 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)] #[derive(Default)]
pub struct CentralPanel {} pub struct CentralPanel {}

View file

@ -12,6 +12,14 @@ use super::*;
/// * if the window has a scroll area (off by default) /// * 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 the window can be collapsed (minimized) to just the title bar (yes, by default)
/// * if there should be a close button (none 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> { pub struct Window<'open> {
title_label: Label, title_label: Label,
open: Option<&'open mut bool>, open: Option<&'open mut bool>,
@ -24,7 +32,7 @@ pub struct Window<'open> {
} }
impl<'open> 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)`. /// This is true even if you disable the title bar with `.title_bar(false)`.
pub fn new(title: impl Into<String>) -> Self { pub fn new(title: impl Into<String>) -> Self {
let title = title.into(); let title = title.into();

View file

@ -64,7 +64,7 @@ impl FrameState {
pub fn available_rect(&self) -> Rect { pub fn available_rect(&self) -> Rect {
debug_assert!( debug_assert!(
self.available_rect.is_finite(), self.available_rect.is_finite(),
"Called `available_rect()` before `begin_frame()`" "Called `available_rect()` before `CtxRef::begin_frame()`"
); );
self.available_rect self.available_rect
} }
@ -101,8 +101,8 @@ impl FrameState {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// A wrapper around `CtxRef`. /// A wrapper around [`Arc`](std::sync::Arc)`<`[`Context`]`>`.
/// This is how you will normally access a [`Context`]. /// This is how you will normally create and access a [`Context`].
#[derive(Clone)] #[derive(Clone)]
pub struct CtxRef(std::sync::Arc<Context>); pub struct CtxRef(std::sync::Arc<Context>);
@ -145,7 +145,7 @@ impl Default for CtxRef {
impl CtxRef { impl CtxRef {
/// Call at the start of every frame. /// 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) { pub fn begin_frame(&mut self, new_input: RawInput) {
let mut self_: Context = (*self.0).clone(); let mut self_: Context = (*self.0).clone();
self_.begin_frame_mut(new_input); 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. /// 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. /// Call this for [`Id`]:s that need interaction or persistence.
pub(crate) fn register_interaction_id(&self, id: Id, new_pos: Pos2) { pub(crate) fn register_interaction_id(&self, id: Id, new_pos: Pos2) {
let prev_pos = self.memory().used_ids.insert(id, new_pos); let prev_pos = self.memory().used_ids.insert(id, new_pos);
if let Some(prev_pos) = prev_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. /// Contains the [`InputState`], [`Memory`], [`Output`], options and more.
/// `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.
// TODO: too many mutexes. Maybe put it all behind one Mutex instead. // TODO: too many mutexes. Maybe put it all behind one Mutex instead.
#[derive(Default)] #[derive(Default)]
pub struct Context { pub struct Context {
@ -442,17 +439,17 @@ impl Context {
&self.input &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. /// That's because since we don't know the proper `pixels_per_point` until then.
pub fn fonts(&self) -> &Fonts { pub fn fonts(&self) -> &Fonts {
&*self &*self
.fonts .fonts
.as_ref() .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.. /// The Egui texture, containing font characters etc.
/// 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. /// That's because since we don't know the proper `pixels_per_point` until then.
pub fn texture(&self) -> Arc<paint::Texture> { pub fn texture(&self) -> Arc<paint::Texture> {
self.fonts().texture() self.fonts().texture()
@ -464,14 +461,17 @@ impl Context {
self.options.lock().font_definitions = font_definitions; self.options.lock().font_definitions = font_definitions;
} }
/// The [`Style`] used by all new windows, panels etc.
pub fn style(&self) -> Arc<Style> { pub fn style(&self) -> Arc<Style> {
self.options.lock().style.clone() self.options.lock().style.clone()
} }
/// The [`Style`] used by all new windows, panels etc.
pub fn set_style(&self, style: impl Into<Arc<Style>>) { pub fn set_style(&self, style: impl Into<Arc<Style>>) {
self.options.lock().style = style.into(); self.options.lock().style = style.into();
} }
/// The number of physical pixels for each logical point.
pub fn pixels_per_point(&self) -> f32 { pub fn pixels_per_point(&self) -> f32 {
self.input.pixels_per_point() self.input.pixels_per_point()
} }
@ -643,22 +643,21 @@ impl Context {
} }
/// True if Egui is currently interested in the mouse. /// True if Egui is currently interested in the mouse.
/// Could be the mouse is hovering over a Egui window, /// Could be the mouse is hovering over a [`Window`] or the user is dragging a widget.
/// or the user is dragging an Egui widget. /// If `false`, the mouse is outside of any Egui area and so
/// 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). /// 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 { pub fn wants_mouse_input(&self) -> bool {
self.is_using_mouse() || (self.is_mouse_over_area() && !self.input().mouse.down) 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). /// 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 { pub fn is_using_mouse(&self) -> bool {
self.memory().interaction.is_using_mouse() 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 { pub fn wants_keyboard_input(&self) -> bool {
self.memory().interaction.kb_focus_id.is_some() 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 = 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. /// 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 { pub fn animate_bool(&self, id: Id, value: bool) -> f32 {
let animation_time = self.style().animation_time; let animation_time = self.style().animation_time;
let animated_value = 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)"));` /// Example: `ui.add(github_link_file_line!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export] #[macro_export]
macro_rules! github_link_file_line { 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)"));` /// Example: `ui.add(github_link_file!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));`
#[macro_export] #[macro_export]
macro_rules! github_link_file { 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)] #[doc(hidden)]
#[macro_export] #[macro_export]
macro_rules! __egui_github_link_file { 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)] #[doc(hidden)]
#[macro_export] #[macro_export]
macro_rules! __egui_github_link_file_line { 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 /// The new mouse press must come within this many seconds from previous mouse release
const MAX_CLICK_DELAY: f64 = 0.3; 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()`. /// 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)] #[derive(Clone, Debug)]
pub struct InputState { pub struct InputState {
/// The raw input we got this frame /// 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)] #[derive(Clone, Debug)]
pub struct MouseInput { pub struct MouseInput {
/// Is the button currently down? /// 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)] #[derive(Clone, Debug, Eq, PartialEq)]
pub enum Event { pub enum Event {
/// The integration detected a "copy" event (e.g. Cmd+C).
Copy, Copy,
/// The integration detected a "cut" event (e.g. Cmd+X).
Cut, Cut,
/// Text input, e.g. via keyboard or paste action. /// 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), Text(String),
Key { Key {
key: Key, key: Key,

View file

@ -38,7 +38,7 @@ impl Order {
} }
/// An identifier for a paint layer. /// 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)] #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct LayerId { 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)] #[derive(Clone, Copy, PartialEq)]
pub struct PaintCmdIdx(usize); 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)] #[derive(Clone, Default)]
pub struct PaintList(Vec<(Rect, PaintCmd)>); 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`. /// 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. /// It is what is used and updated by [`Layout`] when adding new widgets.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Region { pub struct Region {
/// This is the minimal size of the `Ui`. /// 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)] #[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[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)] #[derive(Clone, Copy, Debug, PartialEq)]
// #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] // #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Layout { pub struct Layout {

View file

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

View file

@ -1,4 +1,8 @@
//! Vectors, positions, rectangles etc. //! 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}; 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 { pub trait One {
fn one() -> Self; fn one() -> Self;
} }
@ -28,6 +33,7 @@ impl One for f64 {
} }
} }
/// Helper trait to implement [`lerp`] and [`remap`].
pub trait Real: pub trait Real:
Copy Copy
+ PartialEq + 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. /// 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) /// The `epsilon` can be `f32::EPSILON` to handle simple transforms (like degrees -> radians)
/// but should be higher to handle more complex transformations. /// 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 { pub trait NumExt {
/// More readable version of `self.max(lower_limit)` /// More readable version of `self.max(lower_limit)`
fn at_least(self, lower_limit: Self) -> Self; fn at_least(self, lower_limit: Self) -> Self;
@ -231,62 +239,21 @@ pub trait NumExt {
fn at_most(self, upper_limit: Self) -> Self; fn at_most(self, upper_limit: Self) -> Self;
} }
impl NumExt for f32 { macro_rules! impl_num_ext {
/// More readable version of `self.max(lower_limit)` ($t: ty) => {
impl NumExt for $t {
fn at_least(self, lower_limit: Self) -> Self { fn at_least(self, lower_limit: Self) -> Self {
self.max(lower_limit) self.max(lower_limit)
} }
/// More readable version of `self.min(upper_limit)`
fn at_most(self, upper_limit: Self) -> Self { fn at_most(self, upper_limit: Self) -> Self {
self.min(upper_limit) self.min(upper_limit)
} }
}
};
} }
impl NumExt for f64 { impl_num_ext!(f32);
/// More readable version of `self.max(lower_limit)` impl_num_ext!(f64);
fn at_least(self, lower_limit: Self) -> Self { impl_num_ext!(usize);
self.max(lower_limit) impl_num_ext!(Vec2);
} impl_num_ext!(Pos2);
/// 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)
}
}

View file

@ -2,10 +2,12 @@ use std::ops::{Add, AddAssign, RangeInclusive, Sub, SubAssign};
use crate::math::*; use crate::math::*;
// Sometimes called a Point. I prefer the shorter `Pos2` so it is equal length to `Vec2`
/// A position on screen. /// 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)] #[derive(Clone, Copy, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Pos2 { pub struct Pos2 {
@ -14,6 +16,8 @@ pub struct Pos2 {
// implicit w = 1 // implicit w = 1
} }
/// `pos2(x,y) == Pos2::new(x, y)`
#[inline(always)]
pub const fn pos2(x: f32, y: f32) -> Pos2 { pub const fn pos2(x: f32, y: f32) -> Pos2 {
Pos2 { x, y } Pos2 { x, y }
} }
@ -35,6 +39,8 @@ impl Pos2 {
Self { x, y } 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 { pub fn to_vec2(self) -> Vec2 {
Vec2 { Vec2 {
x: self.x, 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. // `vec2(c,s)` represents where the X axis will end up after rotation.
// //
/// Represents a rotation in the 2D plane. /// 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). /// Normally a `Rot2` is normalized (unit-length).
/// If not, it will also scale vectors. /// If not, it will also scale vectors.
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
@ -32,7 +32,7 @@ impl Rot2 {
Self { s: 0.0, c: 1.0 } 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 { pub fn from_angle(angle: f32) -> Self {
let (s, c) = angle.sin_cos(); let (s, c) = angle.sin_cos();
Self { s, c } 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 #![allow(clippy::float_cmp)] // I know what I'm doing
const NUM_DECIMALS: usize = 15; 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::*; 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)] #[derive(Clone, Copy, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Vec2 { pub struct Vec2 {
@ -12,6 +15,7 @@ pub struct Vec2 {
pub y: f32, pub y: f32,
} }
/// `vec2(x,y) == Vec2::new(x, y)`
#[inline(always)] #[inline(always)]
pub const fn vec2(x: f32, y: f32) -> Vec2 { pub const fn vec2(x: f32, y: f32) -> Vec2 {
Vec2 { x, y } Vec2 { x, y }
@ -75,6 +79,9 @@ impl Vec2 {
self.x * self.x + self.y * self.y 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 { pub fn angled(angle: f32) -> Self {
vec2(angle.cos(), angle.sin()) vec2(angle.cos(), angle.sin())
} }
@ -94,6 +101,7 @@ impl Vec2 {
vec2(self.x.ceil(), self.y.ceil()) vec2(self.x.ceil(), self.y.ceil())
} }
/// True if all members are also finite.
pub fn is_finite(self) -> bool { pub fn is_finite(self) -> bool {
self.x.is_finite() && self.y.is_finite() 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)] #[derive(Clone, Debug)]
pub enum PaintCmd { pub enum PaintCmd {
/// Paint nothing. This can be useful as a placeholder. /// Paint nothing. This can be useful as a placeholder.

View file

@ -1,6 +1,4 @@
//! Graphics module. //! 2D graphics/rendering. Fonts, textures, color, geometry, tesselation etc.
//!
//! Handles fonts, textures, color, geometry and tesselation.
pub mod color; pub mod color;
pub mod command; 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. /// 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)] #[derive(Clone)]
pub struct Painter { pub struct Painter {
/// Source of fonts and destination of paint commands /// Source of fonts and destination of paint commands

View file

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

View file

@ -22,6 +22,9 @@ pub struct Output {
pub needs_repaint: bool, 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)] #[derive(Clone, Copy)]
// #[cfg_attr(feature = "serde", derive(serde::Serialize))] // #[cfg_attr(feature = "serde", derive(serde::Serialize))]
// #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] // #[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. /// This lets you know whether or not a widget has been clicked this frame.
/// It also lets you easily show a tooltip on hover. /// 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. /// The area of the screen we are talking about.
pub rect: Rect, 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, pub sense: Sense,
// OUT: // OUT:
@ -88,8 +91,17 @@ pub struct Response {
/// The widget had keyboard focus and lost it, /// The widget had keyboard focus and lost it,
/// perhaps because the user pressed enter. /// perhaps because the user pressed enter.
/// This is often a signal to the user to the application /// If you want to do an action when a user presses enter in a text field,
/// to make use of the contents of the 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, pub lost_kb_focus: bool,
} }
@ -246,6 +258,7 @@ impl Sense {
Sense::hover() Sense::hover()
} }
/// Sense clicks and hover, but not drags.
pub fn click() -> Self { pub fn click() -> Self {
Self { Self {
click: true, click: true,
@ -253,6 +266,7 @@ impl Sense {
} }
} }
/// Sense drags and hover, but not clicks.
pub fn drag() -> Self { pub fn drag() -> Self {
Self { Self {
click: false, 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 { pub fn click_and_drag() -> Self {
Self { Self {
click: true, click: true,
@ -268,6 +282,7 @@ impl Sense {
} }
} }
/// The logical "or" of two `Sense`s.
#[must_use] #[must_use]
pub fn union(self, other: Self) -> Self { pub fn union(self, other: Self) -> Self {
Self { Self {

View file

@ -4,8 +4,19 @@ use std::{hash::Hash, sync::Arc};
use crate::{color::*, containers::*, layout::*, mutex::MutexGuard, paint::*, widgets::*, *}; use crate::{color::*, containers::*, layout::*, mutex::MutexGuard, paint::*, widgets::*, *};
/// Represents a region of the screen /// This is what you use to place widgets.
/// with a type of layout (horizontal or vertical). ///
/// 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 { pub struct Ui {
/// ID of this ui. /// ID of this ui.
/// Generated based on id of parent ui together with /// 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 { pub fn id(&self) -> Id {
self.id self.id
} }
@ -96,10 +108,12 @@ impl Ui {
Arc::make_mut(&mut self.style) // clone-on-write 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>>) { pub fn set_style(&mut self, style: impl Into<Arc<Style>>) {
self.style = style.into(); self.style = style.into();
} }
/// Get a reference to the parent [`CtxRef`].
pub fn ctx(&self) -> &CtxRef { pub fn ctx(&self) -> &CtxRef {
self.painter.ctx() self.painter.ctx()
} }
@ -588,6 +602,17 @@ impl Ui {
/// # Adding widgets /// # Adding widgets
impl Ui { 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 { pub fn add(&mut self, widget: impl Widget) -> Response {
widget.ui(self) 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; pub(crate) mod cache;
mod history; mod history;

View file

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

View file

@ -16,7 +16,7 @@ fn set(value_function: &mut GetSetValue<'_>, value: f64) {
(value_function)(Some(value)); (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> { pub struct DragValue<'a> {
value_function: GetSetValue<'a>, value_function: GetSetValue<'a>,
speed: f32, speed: f32,

View file

@ -1,5 +1,6 @@
use crate::*; 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);`"] #[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Image { 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: //! Example widget uses:
//! * `ui.add(Label::new("Text").text_color(color::red));` //! * `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);`"] #[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub trait Widget { pub trait Widget {
/// Allocate space, interact, paint, and return a [`Response`].
fn ui(self, ui: &mut Ui) -> 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. /// One out of several alternatives, either selected or not.
/// Will mark selected items with a different background color /// 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);`"] #[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
#[derive(Debug)] #[derive(Debug)]
pub struct SelectableLabel { 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);`"] #[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct Separator { pub struct Separator {
spacing: f32, spacing: f32,

View file

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