From b79c76b9ce74740a6b43004e42f5e81cd1d46610 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Jul 2020 14:35:12 +0200 Subject: [PATCH] [doc] improve Egui documentation --- egui/src/containers.rs | 16 +++++----- egui/src/containers/window.rs | 2 +- egui/src/demos/app.rs | 14 +++------ egui/src/demos/fractal_clock.rs | 2 +- egui/src/id.rs | 54 ++++++++++++++++----------------- egui/src/layers.rs | 2 +- egui/src/layout.rs | 5 +-- egui/src/lib.rs | 2 +- egui/src/math.rs | 16 +++++++++- egui/src/memory.rs | 8 ++++- egui/src/paint/color.rs | 4 +-- egui/src/paint/fonts.rs | 2 +- egui/src/paint/texture_atlas.rs | 7 +++-- egui/src/style.rs | 1 + egui/src/types.rs | 11 ++++++- egui/src/ui.rs | 45 +++++++++++++++------------ egui/src/widgets.rs | 20 +++++++----- 17 files changed, 124 insertions(+), 87 deletions(-) diff --git a/egui/src/containers.rs b/egui/src/containers.rs index 364856dc13f..fd6f84c358c 100644 --- a/egui/src/containers.rs +++ b/egui/src/containers.rs @@ -1,11 +1,11 @@ -pub mod area; -pub mod collapsing_header; -pub mod frame; -pub mod menu; -pub mod popup; -pub mod resize; -pub mod scroll_area; -pub mod window; +pub(crate) mod area; +pub(crate) mod collapsing_header; +pub(crate) mod frame; +pub(crate) mod menu; +pub(crate) mod popup; +pub(crate) mod resize; +pub(crate) mod scroll_area; +pub(crate) mod window; pub use { area::Area, collapsing_header::CollapsingHeader, frame::Frame, popup::*, resize::Resize, diff --git a/egui/src/containers/window.rs b/egui/src/containers/window.rs index a0a70f59164..c8bfc7f2833 100644 --- a/egui/src/containers/window.rs +++ b/egui/src/containers/window.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use crate::{widgets::*, *}; +use crate::{paint::*, widgets::*, *}; use super::*; diff --git a/egui/src/demos/app.rs b/egui/src/demos/app.rs index b7783887bd4..e20c4ae783c 100644 --- a/egui/src/demos/app.rs +++ b/egui/src/demos/app.rs @@ -1,6 +1,6 @@ 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| { - if ui.add(radio(self.radio == 0, "First")).clicked { - self.radio = 0; - } - 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.radio_value("First", &mut self.radio, 0); + ui.radio_value("Second", &mut self.radio, 1); + ui.radio_value("Final", &mut self.radio, 2); }); ui.add(Checkbox::new(&mut self.button_enabled, "Button enabled")); diff --git a/egui/src/demos/fractal_clock.rs b/egui/src/demos/fractal_clock.rs index b713f67fae9..fad845eda57 100644 --- a/egui/src/demos/fractal_clock.rs +++ b/egui/src/demos/fractal_clock.rs @@ -1,6 +1,6 @@ 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", serde(default))] diff --git a/egui/src/id.rs b/egui/src/id.rs index d741d78bad8..f1c58f682c3 100644 --- a/egui/src/id.rs +++ b/egui/src/id.rs @@ -1,34 +1,32 @@ -//! 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 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`. +// TODO: have separate types `PositionId` and `UniqueId`. ? 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)] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] pub struct Id(u64); diff --git a/egui/src/layers.rs b/egui/src/layers.rs index b3aa37c2971..09de19d90fe 100644 --- a/egui/src/layers.rs +++ b/egui/src/layers.rs @@ -37,7 +37,7 @@ impl Layer { /// Each `PaintCmd` is paired with a clip rectangle. type PaintList = Vec<(Rect, PaintCmd)>; -/// TODO: improve this +// TODO: improve this #[derive(Clone, Default)] pub struct GraphicLayers(AHashMap); diff --git a/egui/src/layout.rs b/egui/src/layout.rs index d5ee518988c..95ef1d23713 100644 --- a/egui/src/layout.rs +++ b/egui/src/layout.rs @@ -39,7 +39,7 @@ impl Default for Align { /// 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 -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 { Align::Min => rect.left(), 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)] // #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] pub struct Layout { @@ -146,7 +147,7 @@ impl Layout { /// Reserve this much space and move the cursor. /// 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*. /// 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. diff --git a/egui/src/lib.rs b/egui/src/lib.rs index 71a2f4485bf..baa784b0c1c 100644 --- a/egui/src/lib.rs +++ b/egui/src/lib.rs @@ -50,7 +50,7 @@ pub use { math::*, memory::Memory, movement_tracker::MovementTracker, - paint::{color, Color, TextStyle, Texture}, + paint::{color, Color, PaintJobs, TextStyle, Texture}, style::Style, types::*, ui::Ui, diff --git a/egui/src/math.rs b/egui/src/math.rs index 13e605e1c6c..f7d5dbe75ab 100644 --- a/egui/src/math.rs +++ b/egui/src/math.rs @@ -1,5 +1,8 @@ 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)] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] 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)] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] 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)] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] 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 } +/// 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 fn round_to_precision(value: f32, precision: usize) -> f32 { diff --git a/egui/src/memory.rs b/egui/src/memory.rs index 512a267f219..b3f9f142cf8 100644 --- a/egui/src/memory.rs +++ b/egui/src/memory.rs @@ -6,6 +6,12 @@ use crate::{ 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)] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "with_serde", serde(default))] @@ -30,7 +36,7 @@ pub struct Memory { 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 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 diff --git a/egui/src/paint/color.rs b/egui/src/paint/color.rs index 0661f00e4b4..ed747bdc2f4 100644 --- a/egui/src/paint/color.rs +++ b/egui/src/paint/color.rs @@ -1,5 +1,5 @@ -/// 0-255 `sRGBA`. TODO: rename `sRGBA` for clarity. -/// Uses premultiplied alpha. +// TODO: rename `Color` to `sRGBA` for clarity. +/// 0-255 `sRGBA`. Uses premultiplied alpha. #[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] pub struct Color { diff --git a/egui/src/paint/fonts.rs b/egui/src/paint/fonts.rs index 841603e592a..c1b5f8e3863 100644 --- a/egui/src/paint/fonts.rs +++ b/egui/src/paint/fonts.rs @@ -11,7 +11,7 @@ use super::{ texture_atlas::{Texture, TextureAtlas}, }; -/// TODO: rename +// TODO: rename #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] // #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] pub enum TextStyle { diff --git a/egui/src/paint/texture_atlas.rs b/egui/src/paint/texture_atlas.rs index 48851fa1fb6..9c50a98d343 100644 --- a/egui/src/paint/texture_atlas.rs +++ b/egui/src/paint/texture_atlas.rs @@ -1,7 +1,8 @@ +/// An 8-bit texture containing font data. #[derive(Clone, Default)] pub struct Texture { /// e.g. a hash of the data. Use this to detect changes! - pub id: u64, // TODO + pub id: u64, pub width: usize, pub height: usize, pub pixels: Vec, @@ -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)] pub struct TextureAtlas { texture: Texture, diff --git a/egui/src/style.rs b/egui/src/style.rs index 75778516bfe..972e8fe440f 100644 --- a/egui/src/style.rs +++ b/egui/src/style.rs @@ -3,6 +3,7 @@ use crate::{color::*, math::*, paint::LineStyle, types::*}; // TODO: split into Spacing and Style? +/// Specifies the look and feel of a `Ui`. #[derive(Clone, Debug)] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] pub struct Style { diff --git a/egui/src/types.rs b/egui/src/types.rs index f6f6e573912..0adbf2a46ea 100644 --- a/egui/src/types.rs +++ b/egui/src/types.rs @@ -4,9 +4,12 @@ use crate::{math::Rect, Context, Ui}; // ---------------------------------------------------------------------------- +/// What Egui emits each frame. +/// The backend should use this. #[derive(Clone, Default)] // #[cfg_attr(feature = "with_serde", derive(serde::Serialize))] pub struct Output { + /// Set the cursor to this icon. pub cursor_icon: CursorIcon, /// 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)] // #[cfg_attr(feature = "with_serde", derive(serde::Serialize))] 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 { /// The senses (click or drag) that the widget is interested in (if any). pub sense: Sense, diff --git a/egui/src/ui.rs b/egui/src/ui.rs index 4cd060b1d86..5ee0cb8f6d7 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -112,7 +112,7 @@ impl Ui { 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 { &self.style } @@ -279,9 +279,10 @@ impl Ui { pub fn request_kb_focus(&self, id: Id) { self.memory().kb_focus_id = Some(id); } +} - // ------------------------------------------------------------------------ - +/// # `Id` creation +impl Ui { /// Will warn if the returned id is not guaranteed unique. /// Use this to generate widget ids for widgets that have persistent state in Memory. /// 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 { self.id.with(id_seed) } +} - // ------------------------------------------------------------------------ - // Interaction - +/// # Interaction +impl Ui { pub fn interact(&self, rect: Rect, id: Id, sense: Sense) -> InteractInfo { self.ctx .interact(self.layer, self.clip_rect, rect, Some(id), sense) @@ -374,7 +375,7 @@ impl Ui { /// Reserve this much space and move the cursor. /// 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*. /// 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. @@ -434,10 +435,10 @@ impl Ui { self.child_count += 1; child_rect } +} - // ------------------------------------------------ - // Painting related stuff - +/// # Painting related stuff +impl Ui { /// It is up to the caller to make sure there is room for this. /// Can be used for free painting. /// NOTE: all coordinates are screen coordinates! @@ -524,39 +525,44 @@ impl Ui { color, }); } +} - // ------------------------------------------------------------------------ - // Addding Widgets - +/// # Adding widgets +impl Ui { pub fn add(&mut self, widget: impl Widget) -> GuiResponse { let interact = widget.ui(self); self.response(interact) } - // Convenience functions: - + /// Shortcut for `add(Label::new(text))` pub fn label(&mut self, label: impl Into