[doc] improve docstrings in Egui

This commit is contained in:
Emil Ernerfeldt 2020-08-09 17:24:32 +02:00
parent e26150e46f
commit 3facd5c587
21 changed files with 101 additions and 20 deletions

View file

@ -1,3 +1,7 @@
//! Containers are pieces of the UI which wraps other pieces of 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;
pub(crate) mod frame; pub(crate) mod frame;

View file

@ -6,6 +6,7 @@ use std::{fmt::Debug, hash::Hash, sync::Arc};
use crate::*; use crate::*;
/// State that is persisted between frames
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
pub(crate) struct State { pub(crate) struct State {
@ -31,6 +32,9 @@ impl State {
} }
} }
/// An area on the screen that can be move by dragging.
///
/// This forms the base of the `Window` container.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Area { pub struct Area {
id: Id, id: Id,

View file

@ -146,6 +146,7 @@ impl State {
} }
} }
/// A header which can be collapsed/expanded, revealing a contained `Ui` region.
pub struct CollapsingHeader { pub struct CollapsingHeader {
label: Label, label: Label,
default_open: bool, default_open: bool,

View file

@ -2,6 +2,7 @@
use crate::{layers::PaintCmdIdx, paint::*, *}; use crate::{layers::PaintCmdIdx, paint::*, *};
/// Adds a rectangular frame and background to some `Ui`.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Frame { pub struct Frame {
// On each side // On each side

View file

@ -2,6 +2,7 @@ use std::sync::Arc;
use crate::*; use crate::*;
/// Show a tooltip at the current mouse position (if any).
pub fn show_tooltip(ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) { pub fn show_tooltip(ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) {
if let Some(mouse_pos) = ctx.input().mouse.pos { if let Some(mouse_pos) = ctx.input().mouse.pos {
// TODO: default size // TODO: default size
@ -11,7 +12,7 @@ pub fn show_tooltip(ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) {
} }
} }
/// Show a pop-over window /// Show a pop-over window.
pub fn show_popup( pub fn show_popup(
ctx: &Arc<Context>, ctx: &Arc<Context>,
id: Id, id: Id,

View file

@ -16,6 +16,7 @@ pub(crate) struct State {
pub(crate) requested_size: Option<Vec2>, pub(crate) requested_size: Option<Vec2>,
} }
/// A region that can be resized by dragging the bottom right corner.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Resize { pub struct Resize {
id: Option<Id>, id: Option<Id>,

View file

@ -26,6 +26,7 @@ impl Default for State {
} }
// TODO: rename VScroll // TODO: rename VScroll
/// Add vertical scrolling to a contained `Ui`.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ScrollArea { pub struct ScrollArea {
max_height: f32, max_height: f32,

View file

@ -4,7 +4,7 @@ use crate::{paint::*, widgets::*, *};
use super::*; use super::*;
/// A wrapper around other containers for things you often want in a window /// A floating window which can be moved, closed, collapsed, resized and scrolled.
pub struct Window<'open> { pub struct Window<'open> {
pub title_label: Label, pub title_label: Label,
open: Option<&'open mut bool>, open: Option<&'open mut bool>,

View file

@ -151,6 +151,7 @@ impl Default for MouseInput {
} }
} }
/// An input event. Only covers events used by Egui.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Event { pub enum Event {
Copy, Copy,
@ -164,6 +165,7 @@ pub enum Event {
}, },
} }
/// Keyboard key name. Only covers keys used by Egui.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Key { pub enum Key {
Alt, Alt,

View file

@ -34,6 +34,7 @@ impl Layer {
} }
} }
/// 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);
@ -54,6 +55,12 @@ impl PaintList {
} }
/// Modify an existing command. /// Modify an existing command.
///
/// Sometimes you want to paint a frame behind some contents, but don't know how large the frame needs to be
/// until the contents have been added, and therefor also painted to the `PaintList`.
///
/// The solution is to allocate a `PaintCmd` using `let idx = paint_list.add(cr, PaintCmd::Noop);`
/// and then later setting it using `paint_list.set(idx, cr, frame);`.
pub fn set(&mut self, idx: PaintCmdIdx, clip_rect: Rect, cmd: PaintCmd) { pub fn set(&mut self, idx: PaintCmdIdx, clip_rect: Rect, cmd: PaintCmd) {
assert!(idx.0 < self.0.len()); assert!(idx.0 < self.0.len());
self.0[idx.0] = (clip_rect, cmd); self.0[idx.0] = (clip_rect, cmd);

View file

@ -2,6 +2,7 @@ use crate::{math::*, style::Style};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// `Layout` direction (horizontal or vertical).
#[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))]
#[cfg_attr(feature = "with_serde", serde(rename_all = "snake_case"))] #[cfg_attr(feature = "with_serde", serde(rename_all = "snake_case"))]
@ -16,6 +17,7 @@ impl Default for Direction {
} }
} }
/// left/center/right or top/center/bottom alignment for e.g. anchors and `Layout`s.
#[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))]
#[cfg_attr(feature = "with_serde", serde(rename_all = "snake_case"))] #[cfg_attr(feature = "with_serde", serde(rename_all = "snake_case"))]

View file

@ -1,3 +1,5 @@
//! Vectors, positions, rectangles etc.
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. /// A size or direction in 2D space.
@ -122,6 +124,18 @@ impl Vec2 {
vec2(self.x.max(other.x), self.y.max(other.y)) vec2(self.x.max(other.x), self.y.max(other.y))
} }
/// Returns the minimum of `self.x` and `self.y`.
#[must_use]
pub fn min_elem(self) -> f32 {
self.x.min(self.y)
}
/// Returns the maximum of `self.x` and `self.y`.
#[must_use]
pub fn max_elem(self) -> f32 {
self.x.max(self.y)
}
#[must_use] #[must_use]
pub fn clamp(self, range: RangeInclusive<Self>) -> Self { pub fn clamp(self, range: RangeInclusive<Self>) -> Self {
Self { Self {
@ -575,6 +589,7 @@ impl std::fmt::Debug for Rect {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// Linear interpolation.
pub fn lerp<T>(range: RangeInclusive<T>, t: f32) -> T pub fn lerp<T>(range: RangeInclusive<T>, t: f32) -> T
where where
f32: Mul<T, Output = T>, f32: Mul<T, Output = T>,
@ -583,11 +598,15 @@ where
(1.0 - t) * *range.start() + t * *range.end() (1.0 - t) * *range.start() + t * *range.end()
} }
/// Linearly remap a value from one range to another,
/// so that when `x == from.start()` returns `to.start()`
/// and when `x == from.end()` returns `to.end()`.
pub fn remap(x: f32, from: RangeInclusive<f32>, to: RangeInclusive<f32>) -> f32 { pub fn remap(x: f32, from: RangeInclusive<f32>, to: RangeInclusive<f32>) -> f32 {
let t = (x - from.start()) / (from.end() - from.start()); let t = (x - from.start()) / (from.end() - from.start());
lerp(to, t) lerp(to, t)
} }
/// Like `remap`, but also clamps the value so that the returned value is always in the `to` range.
pub fn remap_clamp(x: f32, from: RangeInclusive<f32>, to: RangeInclusive<f32>) -> f32 { pub fn remap_clamp(x: f32, from: RangeInclusive<f32>, to: RangeInclusive<f32>) -> f32 {
if x <= *from.start() { if x <= *from.start() {
*to.start() *to.start()
@ -604,6 +623,9 @@ pub fn remap_clamp(x: f32, from: RangeInclusive<f32>, to: RangeInclusive<f32>) -
} }
} }
/// Returns `range.start()` if `x <= range.start()`,
/// returns `range.end()` if `x >= range.end()`
/// and returns `x` elsewhen.
pub fn clamp<T>(x: T, range: RangeInclusive<T>) -> T pub fn clamp<T>(x: T, range: RangeInclusive<T>) -> T
where where
T: Copy + PartialOrd, T: Copy + PartialOrd,
@ -629,9 +651,10 @@ pub fn ease_in_ease_out(t: f32) -> f32 {
/// See <https://tauday.com/> /// 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 { /// Round a value to the given number of decimal places.
pub fn round_to_precision(value: f32, decimal_places: usize) -> f32 {
// This is a stupid way of doing this, but stupid works. // This is a stupid way of doing this, but stupid works.
format!("{:.*}", precision, value) format!("{:.*}", decimal_places, value)
.parse() .parse()
.unwrap_or_else(|_| value) .unwrap_or_else(|_| value)
} }

View file

@ -17,9 +17,10 @@
use crate::{widgets::*, *}; use crate::{widgets::*, *};
/// What is saved between frames.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
pub struct BarState { pub(crate) struct BarState {
#[cfg_attr(feature = "with_serde", serde(skip))] #[cfg_attr(feature = "with_serde", serde(skip))]
open_menu: Option<Id>, open_menu: Option<Id>,
#[cfg_attr(feature = "with_serde", serde(skip))] #[cfg_attr(feature = "with_serde", serde(skip))]

View file

@ -1,3 +1,7 @@
//! Graphics module.
//!
//! Handles fonts, textures, color, geometry and tesselation.
pub mod color; pub mod color;
pub mod command; pub mod command;
pub mod font; pub mod font;

View file

@ -9,25 +9,29 @@ use {
crate::math::*, crate::math::*,
}; };
/// The UV coordinate of a white region of the texture mesh.
const WHITE_UV: (u16, u16) = (1, 1); const WHITE_UV: (u16, u16) = (1, 1);
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default)]
pub struct Vertex { pub struct Vertex {
/// Pixel coordinates /// Logical pixel coordinates (points)
pub pos: Pos2, pub pos: Pos2,
/// Texel indices into the texture /// Texel coordinates in the texture
pub uv: (u16, u16), pub uv: (u16, u16),
/// sRGBA, premultiplied alpha /// sRGBA with premultiplied alpha
pub color: Color, pub color: Color,
} }
/// Textured triangles
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Triangles { pub struct Triangles {
/// Draw as triangles (i.e. the length is a multiple of three) /// Draw as triangles (i.e. the length is always multiple of three).
pub indices: Vec<u32>, pub indices: Vec<u32>,
/// The vertex data indexed by `indices`.
pub vertices: Vec<Vertex>, pub vertices: Vec<Vertex>,
} }
/// A clip triangle and some textured triangles.
pub type PaintJob = (Rect, Triangles); pub type PaintJob = (Rect, Triangles);
/// Grouped by clip rectangles, in pixel coordinates /// Grouped by clip rectangles, in pixel coordinates
@ -82,7 +86,7 @@ impl Triangles {
self.vertices.push(bottom_right); self.vertices.push(bottom_right);
} }
/// This is for platsform that only support 16-bit index buffers. /// This is for platforms that only support 16-bit index buffers.
/// Splits this mesh into many small if needed. /// Splits this mesh into many small if needed.
/// All the returned meshes will have indices that fit into a `u16`. /// All the returned meshes will have indices that fit into a `u16`.
pub fn split_to_u16(self) -> Vec<Triangles> { pub fn split_to_u16(self) -> Vec<Triangles> {
@ -150,6 +154,7 @@ pub struct PathPoint {
normal: Vec2, normal: Vec2,
} }
/// A 2D path that can be tesselated into triangles.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Path(Vec<PathPoint>); pub struct Path(Vec<PathPoint>);
@ -313,9 +318,11 @@ use self::PathType::{Closed, Open};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct PaintOptions { pub struct PaintOptions {
/// Anti-aliasing makes shapes appear smoother, but requires more triangles and is therefore slower.
pub anti_alias: bool, pub anti_alias: bool,
/// Size of a pixel in points, e.g. 0.5 /// Size of a pixel in points, e.g. 0.5
pub aa_size: f32, pub aa_size: f32,
/// Output the clip rectangles to be painted?
pub debug_paint_clip_rects: bool, pub debug_paint_clip_rects: bool,
} }
@ -442,6 +449,7 @@ pub fn paint_path_outline(
i0 = i1; i0 = i1;
} }
} else { } else {
// thick line
// TODO: line caps for really thick lines? // TODO: line caps for really thick lines?
/* /*

View file

@ -374,15 +374,15 @@ impl Ui {
/// for `Justified` aligned layouts, like in menus. /// for `Justified` aligned layouts, like in menus.
/// ///
/// You may get LESS space than you asked for if the current layout won't fit what you asked for. /// You may get LESS space than you asked for if the current layout won't fit what you asked for.
pub fn allocate_space(&mut self, child_size: Vec2) -> Rect { pub fn allocate_space(&mut self, desired_size: Vec2) -> Rect {
let child_size = self.painter().round_vec_to_pixels(child_size); let desired_size = self.painter().round_vec_to_pixels(desired_size);
self.cursor = self.painter().round_pos_to_pixels(self.cursor); self.cursor = self.painter().round_pos_to_pixels(self.cursor);
// For debug rendering // For debug rendering
let too_wide = child_size.x > self.available().width(); let too_wide = desired_size.x > self.available().width();
let too_high = child_size.x > self.available().height(); let too_high = desired_size.x > self.available().height();
let rect = self.reserve_space_impl(child_size); let rect = self.reserve_space_impl(desired_size);
if self.style().debug_widget_rects { if self.style().debug_widget_rects {
self.painter.add(PaintCmd::Rect { self.painter.add(PaintCmd::Rect {
@ -429,8 +429,11 @@ impl Ui {
} }
/// Ask to allocate a certain amount of space and return a Painter for that region. /// Ask to allocate a certain amount of space and return a Painter for that region.
pub fn allocate_canvas(&mut self, size: Vec2) -> Painter { ///
let rect = self.allocate_space(size); /// You may get back a `Painter` with a smaller or larger size than what you desired,
/// depending on the avilable space and the current layout.
pub fn allocate_canvas(&mut self, desired_size: Vec2) -> Painter {
let rect = self.allocate_space(desired_size);
self.painter_at(rect) self.painter_at(rect)
} }
} }

View file

@ -1,7 +1,7 @@
//! Widgets are pieces of GUI such as labels, buttons, sliders 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));`
//!
//! * `if ui.add(Button::new("Click me")).clicked { ... }` //! * `if ui.add(Button::new("Click me")).clicked { ... }`
#![allow(clippy::new_without_default)] #![allow(clippy::new_without_default)]
@ -24,6 +24,7 @@ pub trait Widget {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// Static text.
pub struct Label { pub struct Label {
// TODO: not pub // TODO: not pub
pub(crate) text: String, pub(crate) text: String,
@ -146,6 +147,7 @@ impl Into<Label> for String {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// A clickable hyperlink, e.g. to `"https://github.com/emilk/emigui/"`.
pub struct Hyperlink { pub struct Hyperlink {
url: String, url: String,
text: String, text: String,
@ -210,6 +212,7 @@ impl Widget for Hyperlink {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// Clickable button with text
pub struct Button { pub struct Button {
text: String, text: String,
text_color: Option<Color>, text_color: Option<Color>,
@ -298,6 +301,8 @@ impl Widget for Button {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// TODO: allow checkbox without a text label
/// Boolean on/off control with text label
#[derive(Debug)] #[derive(Debug)]
pub struct Checkbox<'a> { pub struct Checkbox<'a> {
checked: &'a mut bool, checked: &'a mut bool,
@ -375,6 +380,7 @@ impl<'a> Widget for Checkbox<'a> {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// One out of several alternatives, either checked or not.
#[derive(Debug)] #[derive(Debug)]
pub struct RadioButton { pub struct RadioButton {
checked: bool, checked: bool,
@ -448,6 +454,7 @@ impl Widget for RadioButton {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// A visual separator. A horizontal or vertical line (depending on `Layout`).
pub struct Separator { pub struct Separator {
line_width: Option<f32>, line_width: Option<f32>,
spacing: f32, spacing: f32,
@ -537,6 +544,7 @@ impl Widget for Separator {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// A floating point value that you can change by dragging the number. More compact than a slider.
pub struct DragValue<'a> { pub struct DragValue<'a> {
value: &'a mut f32, value: &'a mut f32,
speed: f32, speed: f32,

View file

@ -6,6 +6,7 @@ use crate::{paint::*, widgets::Label, *};
/// for the borrow checker. /// for the borrow checker.
type SliderGetSet<'a> = Box<dyn 'a + FnMut(Option<f32>) -> f32>; type SliderGetSet<'a> = Box<dyn 'a + FnMut(Option<f32>) -> f32>;
/// Control a number by a horizontal slider.
pub struct Slider<'a> { pub struct Slider<'a> {
get_set_value: SliderGetSet<'a>, get_set_value: SliderGetSet<'a>,
range: RangeInclusive<f32>, range: RangeInclusive<f32>,

View file

@ -8,6 +8,7 @@ pub(crate) struct State {
pub cursor: Option<usize>, pub cursor: Option<usize>,
} }
/// A text region that the user can edit the contents of.
#[derive(Debug)] #[derive(Debug)]
pub struct TextEdit<'t> { pub struct TextEdit<'t> {
text: &'t mut String, text: &'t mut String,

3
egui_glium/README.md Normal file
View file

@ -0,0 +1,3 @@
# egui_glium
This crates provides bindings between [Egui](crates.io/crates/egui) and [glium](https://crates.io/crates/glium) which allows you to write GUI code using Egui and compile it and run it natively, cross platform.

5
egui_web/README.md Normal file
View file

@ -0,0 +1,5 @@
# egui_web
This crates allows you to compile GUI code written with [Egui](crates.io/crates/egui) to [WASM](https://en.wikipedia.org/wiki/WebAssembly) to run on a web page.
Check out [docs/index.html](https://github.com/emilk/emigui/blob/master/docs/index.html), [demo_web](https://github.com/emilk/emigui/tree/master/demo_web) and [build_web.sh](https://github.com/emilk/emigui/blob/master/build_web.sh) for examples of how to set it up.