Improve documentation

This commit is contained in:
Emil Ernerfeldt 2021-02-07 14:55:39 +01:00
parent a382fad1d0
commit 5ce681ef16
9 changed files with 99 additions and 35 deletions

View file

@ -70,7 +70,7 @@ ui.label(format!("Hello '{}', age {}", name, age));
* Friendly: difficult to make mistakes, and shouldn't panic
* Portable: the same code works on the web and as a native app
* Easy to integrate into any environment
* A simple 2D graphics API for custom painting
* A simple 2D graphics API for custom painting ([`epaint`](https://docs.rs/epaint)).
* No callbacks
* Pure immediate mode
* Extensible: [easy to write your own widgets for egui](https://github.com/emilk/egui/blob/master/egui_demo_lib/src/apps/demo/toggle_switch.rs)

View file

@ -2,10 +2,10 @@
use crate::{layers::ShapeIdx, paint::*, *};
/// Adds a rectangular frame and background to some [`Ui`].
/// Color and margin of a rectangular background of a [`Ui`].
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Frame {
// On each side
/// On each side
pub margin: Vec2,
pub corner_radius: f32,
pub shadow: Shadow,

View file

@ -158,6 +158,7 @@ pub struct CentralPanel {
}
impl CentralPanel {
/// Change the background color, margins, etc.
pub fn frame(mut self, frame: Frame) -> Self {
self.frame = Some(frame);
self

View file

@ -90,8 +90,7 @@ impl<'open> Window<'open> {
self
}
/// Usage: `Window::new(...).frame(|f| f.fill(Some(BLUE)))`
/// Not sure this is a good interface for this.
/// Change the background color, margins, etc.
pub fn frame(mut self, frame: Frame) -> Self {
self.frame = Some(frame);
self
@ -399,6 +398,7 @@ struct PossibleInteractions {
resizable: bool,
}
/// Either a move or resize
#[derive(Clone, Copy, Debug)]
pub(crate) struct WindowInteraction {
pub(crate) area_layer_id: LayerId,
@ -486,6 +486,7 @@ fn move_and_resize_window(ctx: &Context, window_interaction: &WindowInteraction)
Some(rect)
}
/// Returns `Some` if there is a move or resize
fn window_interaction(
ctx: &Context,
possible: PossibleInteractions,

View file

@ -127,6 +127,37 @@ impl FrameState {
/// A wrapper around [`Arc`](std::sync::Arc)`<`[`Context`]`>`.
/// This is how you will normally create and access a [`Context`].
///
/// Almost all methods are marked `&self`, `Context` has interior mutability (protected by mutexes).
///
/// [`CtxRef`] is cheap to clone, and any clones refers to the same mutable data.
///
/// # Example:
///
/// ``` no_run
/// # fn handle_output(_: egui::Output) {}
/// # fn paint(_: Vec<egui::ClippedMesh>) {}
/// let mut ctx = egui::CtxRef::default();
///
/// // Game loop:
/// loop {
/// let raw_input = egui::RawInput::default();
/// ctx.begin_frame(raw_input);
///
/// egui::CentralPanel::default().show(&ctx, |ui| {
/// ui.label("Hello world!");
/// if ui.button("Click me").clicked() {
/// /* take some action here */
/// }
/// });
///
/// let (output, shapes) = ctx.end_frame();
/// let clipped_meshes = ctx.tessellate(shapes); // create triangles to paint
/// handle_output(output);
/// paint(clipped_meshes);
/// }
/// ```
///
#[derive(Clone)]
pub struct CtxRef(std::sync::Arc<Context>);
@ -168,7 +199,11 @@ impl Default for CtxRef {
}
impl CtxRef {
/// Call at the start of every frame.
/// Call at the start of every frame. Match with a call to [`Context::end_frame`].
///
/// This will modify the internal reference to point to a new generation of [`Context`].
/// Any old clones of this [`CtxRef`] will refer to the old [`Context`], which will not get new input.
///
/// 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();
@ -354,7 +389,14 @@ impl CtxRef {
/// This is the first thing you need when working with egui. Create using [`CtxRef`].
///
/// Contains the [`InputState`], [`Memory`], [`Output`], and more.
// TODO: too many mutexes. Maybe put it all behind one Mutex instead.
///
/// Your handle to Egui.
///
/// Almost all methods are marked `&self`, `Context` has interior mutability (protected by mutexes).
/// Multi-threaded access to a [`Context`] is behind the feature flag `multi_threaded`.
/// Normally you'd always do all ui work on one thread, or perhaps use multiple contexts,
/// but if you really want to access the same Context from multiple threads, it *SHOULD* be fine,
/// but you are likely the first person to try it.
#[derive(Default)]
pub struct Context {
/// None until first call to `begin_frame`.
@ -591,8 +633,7 @@ impl Context {
/// Call at the end of each frame.
/// Returns what has happened this frame (`Output`) as well as what you need to paint.
/// You can transform the returned shapes into triangles with a call to
/// `Context::tessellate`.
/// You can transform the returned shapes into triangles with a call to `Context::tessellate`.
#[must_use]
pub fn end_frame(&self) -> (Output, Vec<ClippedShape>) {
if self.input.wants_repaint() {

View file

@ -12,13 +12,13 @@ pub struct RawInput {
/// How many points (logical pixels) the user scrolled
pub scroll_delta: Vec2,
#[deprecated = "Use screen_rect instead: `Some(Rect::from_pos_size(Default::default(), vec2(window_width, window_height)))`"]
#[deprecated = "Use instead: `screen_rect: Some(Rect::from_pos_size(Default::default(), screen_size))`"]
pub screen_size: Vec2,
/// Position and size of the area that egui should use.
/// Usually you would set this to
///
/// `Some(Rect::from_pos_size(Default::default(), vec2(window_width, window_height)))`.
/// `Some(Rect::from_pos_size(Default::default(), screen_size))`.
///
/// but you could also constrain egui to some smaller portion of your window if you like.
///

View file

@ -4,6 +4,40 @@
//! which uses [`eframe`](https://docs.rs/eframe).
//!
//! To create a GUI using egui you first need a [`CtxRef`] (by convention referred to by `ctx`).
//! Then you add a [`Window`] or a [`SidePanel`] to get a [`Ui`], which is what you'll be using to add all the buttons and labels that you need.
//!
//! ## Integrating with egui
//! To write your own integration for egui you need to do this:
//!
//! ``` no_run
//! # fn handle_output(_: egui::Output) {}
//! # fn paint(_: Vec<egui::ClippedMesh>) {}
//! # fn gather_input() -> egui::RawInput { egui::RawInput::default() }
//! let mut ctx = egui::CtxRef::default();
//!
//! // Game loop:
//! loop {
//! let raw_input: egui::RawInput = gather_input();
//! ctx.begin_frame(raw_input);
//!
//! egui::CentralPanel::default().show(&ctx, |ui| {
//! ui.label("Hello world!");
//! if ui.button("Click me").clicked() {
//! /* take some action here */
//! }
//! });
//!
//! let (output, shapes) = ctx.end_frame();
//! let clipped_meshes = ctx.tessellate(shapes); // create triangles to paint
//! handle_output(output);
//! paint(clipped_meshes);
//! }
//! ```
//!
//! ## Using egui
//!
//! To see what is possible to build we egui you can check out the online demo at <https://emilk.github.io/egui/#demo>.
//!
//! Use one of [`SidePanel`], [`TopPanel`], [`CentralPanel`], [`Window`] or [`Area`] to
//! get access to an [`Ui`] where you can put widgets. For example:
//!
@ -11,28 +45,14 @@
//! # let mut ctx = egui::CtxRef::default();
//! # ctx.begin_frame(Default::default());
//! egui::CentralPanel::default().show(&ctx, |ui| {
//! ui.label("Hello");
//! ui.add(egui::Label::new("Hello World!"));
//! ui.label("A shorter and more convenient way to add a label.");
//! if ui.button("Click me").clicked() {
//! /* take some action here */
//! }
//! });
//! ```
//!
//!
//! To write your own integration for egui you need to do this:
//!
//! ``` ignore
//! let mut egui_ctx = egui::CtxRef::default();
//!
//! // Game loop:
//! loop {
//! let raw_input: egui::RawInput = my_integration.gather_input();
//! egui_ctx.begin_frame(raw_input);
//! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here
//! let (output, shapes) = egui_ctx.end_frame();
//! let clipped_meshes = egui_ctx.tessellate(shapes); // create triangles to paint
//! my_integration.paint(clipped_meshes);
//! my_integration.set_cursor_icon(output.cursor_icon);
//! // Also see `egui::Output` for more
//! }
//! ```
#![cfg_attr(not(debug_assertions), deny(warnings))] // Forbid warnings in release builds
#![forbid(unsafe_code)]
@ -133,11 +153,13 @@ pub use {
// ----------------------------------------------------------------------------
/// `true` if egui was compiled with debug assertions enabled.
#[cfg(debug_assertions)]
pub(crate) const fn has_debug_assertions() -> bool {
true
}
/// `true` if egui was compiled with debug assertions enabled.
#[cfg(not(debug_assertions))]
pub(crate) const fn has_debug_assertions() -> bool {
false

View file

@ -348,7 +348,7 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res
/// Shows a button with the given color.
/// If the user clicks the button, a full color picker is shown.
pub fn color_edit_button_srgba(ui: &mut Ui, srgba: &mut Color32, alpha: Alpha) -> Response {
// To ensure we keep hue slider when `srgba` is grey we store the
// To ensure we keep hue slider when `srgba` is gray we store the
// full `Hsva` in a cache:
let mut hsva = ui

View file

@ -91,12 +91,11 @@ impl Rect {
max: pos2(*x_range.end(), *y_range.end()),
}
}
pub fn from_two_pos(a: Pos2, b: Pos2) -> Self {
let (left, right) = if a.x > b.x { (b.x, a.x) } else { (a.x, b.x) };
let (top, bottom) = if a.y > b.y { (b.y, a.y) } else { (a.y, b.y) };
Rect {
min: pos2(left, top),
max: pos2(right, bottom),
min: pos2(a.x.min(b.x), a.y.min(b.y)),
max: pos2(a.x.max(b.x), a.y.max(b.y)),
}
}