Add a lot of documentation and inter-doc links
This commit is contained in:
parent
22e442c613
commit
a1fa9903b0
29 changed files with 226 additions and 138 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)>);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue