improve documentation
This commit is contained in:
parent
8be37b3d6c
commit
fdb1aa6bec
10 changed files with 151 additions and 44 deletions
22
README.md
22
README.md
|
@ -25,6 +25,7 @@ Sections:
|
||||||
* [How it works](#how-it-works)
|
* [How it works](#how-it-works)
|
||||||
* [Integrations](#integrations)
|
* [Integrations](#integrations)
|
||||||
* [Why immediate mode](#why-immediate-mode)
|
* [Why immediate mode](#why-immediate-mode)
|
||||||
|
* [FAQ](#faq)
|
||||||
* [Other](#other)
|
* [Other](#other)
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
@ -141,7 +142,7 @@ Loop:
|
||||||
* Gather input (mouse, touches, keyboard, screen size, etc) and give it to egui
|
* Gather input (mouse, touches, keyboard, screen size, etc) and give it to egui
|
||||||
* Run application code (Immediate Mode GUI)
|
* Run application code (Immediate Mode GUI)
|
||||||
* Tell egui to tessellate the frame graphics to a triangle mesh
|
* Tell egui to tessellate the frame graphics to a triangle mesh
|
||||||
* Render the triangle mesh with your favorite graphics API (see [OpenGL example](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs))
|
* Render the triangle mesh with your favorite graphics API (see [OpenGL example](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs)) or use `eframe`, the egui framework crate.
|
||||||
|
|
||||||
## Integrations
|
## Integrations
|
||||||
|
|
||||||
|
@ -266,13 +267,28 @@ There are some GUI state that you want the GUI library to retain, even in an imm
|
||||||
Overall, ID handling is a rare invonvenience, and not a big disadvantage.
|
Overall, ID handling is a rare invonvenience, and not a big disadvantage.
|
||||||
|
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
Also see [GitHub Discussions](https://github.com/emilk/egui/discussions/categories/q-a).
|
||||||
|
|
||||||
|
### What is the difference between egui and eframe?
|
||||||
|
|
||||||
|
`egui` is a 2D user interface library for laying out and interacting with buttons, sliders, etc.
|
||||||
|
`egui` has no idea if it is running on the web or natively, and does not know how to collect input or show things on screen.
|
||||||
|
That is the job of *the integration* or *backend*.
|
||||||
|
|
||||||
|
It is common to use `egui` from a game engine (using e.g. [`bevy_egui`](https://docs.rs/bevy_egui)),
|
||||||
|
but you can also use `egui` stand-alone using `eframe`. `eframe` has integration for web and native, and handles input and rendering.
|
||||||
|
The _frame_ in `eframe` stands both for the frame in which your egui app resides and also for "framework" (`frame` is a framework, `egui` is a library).
|
||||||
|
|
||||||
|
|
||||||
## Other
|
## Other
|
||||||
|
|
||||||
### Conventions and design choices
|
### Conventions and design choices
|
||||||
|
|
||||||
All coordinates are in screen space coordinates, with (0, 0) in the top left corner
|
All coordinates are in screen space coordinates, with (0, 0) in the top left corner
|
||||||
|
|
||||||
All coordinates are in locial "points" which may consist of many physical pixels.
|
All coordinates are in "points" which may consist of many physical pixels.
|
||||||
|
|
||||||
All colors have premultiplied alpha.
|
All colors have premultiplied alpha.
|
||||||
|
|
||||||
|
@ -286,7 +302,7 @@ The one and only [Dear ImGui](https://github.com/ocornut/imgui) is a great Immed
|
||||||
|
|
||||||
### Name
|
### Name
|
||||||
|
|
||||||
The name of the library and the project is "egui" and pronounced as "e-gooey".
|
The name of the library and the project is "egui" and pronounced as "e-gooey". Please don't write it as "EGUI".
|
||||||
|
|
||||||
The library was originally called "Emigui", but was renamed to "egui" in 2020.
|
The library was originally called "Emigui", but was renamed to "egui" in 2020.
|
||||||
|
|
||||||
|
|
|
@ -7,3 +7,7 @@ This aims to be the entry-level crate if you want to write an egui app.
|
||||||
`eframe` is a very thin crate that re-exports [`egui`](https://crates.io/crates/egui), [`epi`](https://crates.io/crates/epi) and thin wrappers over the backends.
|
`eframe` is a very thin crate that re-exports [`egui`](https://crates.io/crates/egui), [`epi`](https://crates.io/crates/epi) and thin wrappers over the backends.
|
||||||
|
|
||||||
On Linux you need to first run `sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev` to compile `eframe` natively.
|
On Linux you need to first run `sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev` to compile `eframe` natively.
|
||||||
|
|
||||||
|
## Name
|
||||||
|
|
||||||
|
The _frame_ in `eframe` stands both for the frame in which your egui app resides and also for "framework" (`frame` is a framework, `egui` is a library).
|
||||||
|
|
|
@ -122,6 +122,18 @@ pub(crate) fn paint_icon(ui: &mut Ui, openness: f32, response: &Response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A header which can be collapsed/expanded, revealing a contained [`Ui`] region.
|
/// A header which can be collapsed/expanded, revealing a contained [`Ui`] region.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # let ui = &mut egui::Ui::__test();
|
||||||
|
/// egui::CollapsingHeader::new("Heading")
|
||||||
|
/// .show(ui, |ui| {
|
||||||
|
/// ui.label("Contents");
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// // Short version:
|
||||||
|
/// ui.collapsing("Heading", |ui| { ui.label("Contents"); });
|
||||||
|
/// ```
|
||||||
pub struct CollapsingHeader {
|
pub struct CollapsingHeader {
|
||||||
label: Label,
|
label: Label,
|
||||||
default_open: bool,
|
default_open: bool,
|
||||||
|
@ -130,6 +142,11 @@ pub struct CollapsingHeader {
|
||||||
|
|
||||||
impl CollapsingHeader {
|
impl CollapsingHeader {
|
||||||
/// The `CollapsingHeader` starts out collapsed unless you call `default_open`.
|
/// The `CollapsingHeader` starts out collapsed unless you call `default_open`.
|
||||||
|
///
|
||||||
|
/// The label is used as an [`Id`] source.
|
||||||
|
/// If the label is unique and static this is fine,
|
||||||
|
/// but if it changes or there are several `CollapsingHeader` with the same title
|
||||||
|
/// you need to provide a unique id source with [`Self::id_source`].
|
||||||
pub fn new(label: impl Into<String>) -> Self {
|
pub fn new(label: impl Into<String>) -> Self {
|
||||||
let label = Label::new(label).text_style(TextStyle::Button).wrap(false);
|
let label = Label::new(label).text_style(TextStyle::Button).wrap(false);
|
||||||
let id_source = Id::new(label.text());
|
let id_source = Id::new(label.text());
|
||||||
|
@ -140,6 +157,8 @@ impl CollapsingHeader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// By default, the `CollapsingHeader` is collapsed.
|
||||||
|
/// Call `.default_open(true)` to change this.
|
||||||
pub fn default_open(mut self, open: bool) -> Self {
|
pub fn default_open(mut self, open: bool) -> Self {
|
||||||
self.default_open = open;
|
self.default_open = open;
|
||||||
self
|
self
|
||||||
|
|
|
@ -42,7 +42,11 @@ pub struct RawInput {
|
||||||
/// Which modifier keys are down at the start of the frame?
|
/// Which modifier keys are down at the start of the frame?
|
||||||
pub modifiers: Modifiers,
|
pub modifiers: Modifiers,
|
||||||
|
|
||||||
/// In-order events received this frame
|
/// In-order events received this frame.
|
||||||
|
///
|
||||||
|
/// There is currently no way to know if egui handles a particular event,
|
||||||
|
/// but you can check if egui is using the keyboard with [`crate::Context::wants_keyboard_input`]
|
||||||
|
/// and/or the pointer (mouse/touch) with [`crate::Context::is_using_pointer`].
|
||||||
pub events: Vec<Event>,
|
pub events: Vec<Event>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,9 @@ impl GridLayout {
|
||||||
|
|
||||||
/// A simple grid layout.
|
/// A simple grid layout.
|
||||||
///
|
///
|
||||||
/// The contents of each cell be aligned to the left and center.
|
/// The cells are always layed out left to right, top-down.
|
||||||
|
/// The contents of each cell will be aligned to the left and center.
|
||||||
|
///
|
||||||
/// If you want to add multiple widgets to a cell you need to group them with
|
/// If you want to add multiple widgets to a cell you need to group them with
|
||||||
/// [`Ui::horizontal`], [`Ui::vertical`] etc.
|
/// [`Ui::horizontal`], [`Ui::vertical`] etc.
|
||||||
///
|
///
|
||||||
|
|
|
@ -9,41 +9,32 @@
|
||||||
//! 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.
|
//! 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
|
//! # Using egui
|
||||||
//!
|
//!
|
||||||
//! To write your own integration for egui you need to do this:
|
//! To see what is possible to build with egui you can check out the online demo at <https://emilk.github.io/egui/#demo>.
|
||||||
//!
|
//!
|
||||||
//! ``` no_run
|
//! If you like the "learning by doing" approach, clone <https://github.com/emilk/egui_template> and get started using egui right away.
|
||||||
//! # 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:
|
//! ### A simple example
|
||||||
//! loop {
|
|
||||||
//! let raw_input: egui::RawInput = gather_input();
|
|
||||||
//! ctx.begin_frame(raw_input);
|
|
||||||
//!
|
//!
|
||||||
//! egui::CentralPanel::default().show(&ctx, |ui| {
|
//! Here is a simple counter that can be incremented and decremented using two buttons:
|
||||||
//! ui.label("Hello world!");
|
//! ```
|
||||||
//! if ui.button("Click me").clicked() {
|
//! fn ui_counter(ui: &mut egui::Ui, counter: &mut i32) {
|
||||||
//! /* take some action here */
|
//! // Put the buttons and label on the same row:
|
||||||
|
//! ui.horizontal(|ui| {
|
||||||
|
//! if ui.button("-").clicked() {
|
||||||
|
//! *counter -= 1;
|
||||||
|
//! }
|
||||||
|
//! ui.label(counter.to_string());
|
||||||
|
//! if ui.button("+").clicked() {
|
||||||
|
//! *counter += 1;
|
||||||
//! }
|
//! }
|
||||||
//! });
|
//! });
|
||||||
//!
|
|
||||||
//! let (output, shapes) = ctx.end_frame();
|
|
||||||
//! let clipped_meshes = ctx.tessellate(shapes); // create triangles to paint
|
|
||||||
//! handle_output(output);
|
|
||||||
//! paint(clipped_meshes);
|
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//!
|
//! In some GUI frameworks this would require defining multiple types and functions with callbacks or message handlers,
|
||||||
//! ## Using egui
|
//! but thanks to `egui` being immediate mode everything is one self-contained function!
|
||||||
//!
|
|
||||||
//! To see what is possible to build we egui you can check out the online demo at <https://emilk.github.io/egui/#demo>.
|
|
||||||
//!
|
|
||||||
//! If you like the "learning by doing" approach, clone <https://github.com/emilk/egui_template> and get started using egui right away.
|
|
||||||
//!
|
//!
|
||||||
//! ### Getting a [`Ui`]
|
//! ### Getting a [`Ui`]
|
||||||
//!
|
//!
|
||||||
|
@ -89,6 +80,9 @@
|
||||||
//!
|
//!
|
||||||
//! ui.separator();
|
//! ui.separator();
|
||||||
//!
|
//!
|
||||||
|
//! # let my_image = egui::TextureId::default();
|
||||||
|
//! ui.image(my_image, [640.0, 480.0]);
|
||||||
|
//!
|
||||||
//! ui.collapsing("Click to see what is hidden!", |ui| {
|
//! ui.collapsing("Click to see what is hidden!", |ui| {
|
||||||
//! ui.label("Not much, as it turns out");
|
//! ui.label("Not much, as it turns out");
|
||||||
//! });
|
//! });
|
||||||
|
@ -101,9 +95,42 @@
|
||||||
//! * angles are in radians
|
//! * angles are in radians
|
||||||
//! * `Vec2::X` is right and `Vec2::Y` is down.
|
//! * `Vec2::X` is right and `Vec2::Y` is down.
|
||||||
//! * `Pos2::ZERO` is left top.
|
//! * `Pos2::ZERO` is left top.
|
||||||
|
//! * Positions and sizes are measured in _points_. Each point may consist of many physical pixels.
|
||||||
|
//!
|
||||||
|
//! # Integrating with egui
|
||||||
|
//!
|
||||||
|
//! Most likely you are using an existing `egui` backend/integration such as [`eframe`](https://docs.rs/eframe) or [`bevy_egui`](https://docs.rs/bevy_egui),
|
||||||
|
//! but if you want to integrate `egui` into a new game engine, this is the section for you.
|
||||||
|
//!
|
||||||
|
//! 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);
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! ## Understanding immediate mode
|
//! # Understanding immediate mode
|
||||||
//!
|
//!
|
||||||
//! `egui` is an immediate mode GUI library. It is useful to fully grok what "immediate mode" implies.
|
//! `egui` is an immediate mode GUI library. It is useful to fully grok what "immediate mode" implies.
|
||||||
//!
|
//!
|
||||||
|
@ -111,7 +138,9 @@
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # let ui = &mut egui::Ui::__test();
|
//! # let ui = &mut egui::Ui::__test();
|
||||||
//! if ui.button("click me").clicked() { take_action() }
|
//! if ui.button("click me").clicked() {
|
||||||
|
//! take_action()
|
||||||
|
//! }
|
||||||
//! # fn take_action() {}
|
//! # fn take_action() {}
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
@ -169,7 +198,7 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! # Code snippets
|
//! ## Code snippets
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # let ui = &mut egui::Ui::__test();
|
//! # let ui = &mut egui::Ui::__test();
|
||||||
|
|
|
@ -76,7 +76,7 @@ pub struct Spacing {
|
||||||
/// Anything clickable should be (at least) this size.
|
/// Anything clickable should be (at least) this size.
|
||||||
pub interact_size: Vec2, // TODO: rename min_interact_size ?
|
pub interact_size: Vec2, // TODO: rename min_interact_size ?
|
||||||
|
|
||||||
/// Default width of a `Slider`.
|
/// Default width of a `Slider` and `ComboBox`.
|
||||||
pub slider_width: f32, // TODO: rename big_interact_size ?
|
pub slider_width: f32, // TODO: rename big_interact_size ?
|
||||||
|
|
||||||
/// Default width of a `TextEdit`.
|
/// Default width of a `TextEdit`.
|
||||||
|
|
|
@ -747,7 +747,7 @@ impl Ui {
|
||||||
|
|
||||||
/// # Adding widgets
|
/// # Adding widgets
|
||||||
impl Ui {
|
impl Ui {
|
||||||
/// Add a widget to this `Ui` at a location dependent on the current [`Layout`].
|
/// Add a [`Widget`] to this `Ui` at a location dependent on the current [`Layout`].
|
||||||
///
|
///
|
||||||
/// The returned [`Response`] can be used to check for interactions,
|
/// The returned [`Response`] can be used to check for interactions,
|
||||||
/// as well as adding tooltips using [`Response::on_hover_text`].
|
/// as well as adding tooltips using [`Response::on_hover_text`].
|
||||||
|
@ -762,7 +762,7 @@ impl Ui {
|
||||||
widget.ui(self)
|
widget.ui(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a widget to this `Ui` with a given max size.
|
/// Add a [`Widget`] to this `Ui` with a given max size.
|
||||||
pub fn add_sized(&mut self, max_size: Vec2, widget: impl Widget) -> Response {
|
pub fn add_sized(&mut self, max_size: Vec2, widget: impl Widget) -> Response {
|
||||||
self.allocate_ui(max_size, |ui| {
|
self.allocate_ui(max_size, |ui| {
|
||||||
ui.centered_and_justified(|ui| ui.add(widget)).inner
|
ui.centered_and_justified(|ui| ui.add(widget)).inner
|
||||||
|
@ -770,7 +770,7 @@ impl Ui {
|
||||||
.inner
|
.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a widget to this `Ui` at a specific location (manual layout).
|
/// Add a [`Widget`] to this `Ui` at a specific location (manual layout).
|
||||||
pub fn put(&mut self, max_rect: Rect, widget: impl Widget) -> Response {
|
pub fn put(&mut self, max_rect: Rect, widget: impl Widget) -> Response {
|
||||||
self.allocate_ui_at_rect(max_rect, |ui| {
|
self.allocate_ui_at_rect(max_rect, |ui| {
|
||||||
ui.centered_and_justified(|ui| ui.add(widget)).inner
|
ui.centered_and_justified(|ui| ui.add(widget)).inner
|
||||||
|
@ -779,6 +779,8 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shortcut for `add(Label::new(text))`
|
/// Shortcut for `add(Label::new(text))`
|
||||||
|
///
|
||||||
|
/// Se also [`Label`].
|
||||||
pub fn label(&mut self, label: impl Into<Label>) -> Response {
|
pub fn label(&mut self, label: impl Into<Label>) -> Response {
|
||||||
self.add(label.into())
|
self.add(label.into())
|
||||||
}
|
}
|
||||||
|
@ -815,6 +817,8 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shortcut for `add(Hyperlink::new(url))`
|
/// Shortcut for `add(Hyperlink::new(url))`
|
||||||
|
///
|
||||||
|
/// Se also [`Hyperlink`].
|
||||||
pub fn hyperlink(&mut self, url: impl Into<String>) -> Response {
|
pub fn hyperlink(&mut self, url: impl Into<String>) -> Response {
|
||||||
self.add(Hyperlink::new(url))
|
self.add(Hyperlink::new(url))
|
||||||
}
|
}
|
||||||
|
@ -825,6 +829,8 @@ impl Ui {
|
||||||
/// # let ui = &mut egui::Ui::__test();
|
/// # let ui = &mut egui::Ui::__test();
|
||||||
/// ui.hyperlink_to("egui on GitHub", "https://www.github.com/emilk/egui/");
|
/// ui.hyperlink_to("egui on GitHub", "https://www.github.com/emilk/egui/");
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// Se also [`Hyperlink`].
|
||||||
pub fn hyperlink_to(&mut self, label: impl Into<String>, url: impl Into<String>) -> Response {
|
pub fn hyperlink_to(&mut self, label: impl Into<String>, url: impl Into<String>) -> Response {
|
||||||
self.add(Hyperlink::new(url).text(label))
|
self.add(Hyperlink::new(url).text(label))
|
||||||
}
|
}
|
||||||
|
@ -835,11 +841,15 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Now newlines (`\n`) allowed. Pressing enter key will result in the `TextEdit` loosing focus (`response.lost_kb_focus`).
|
/// Now newlines (`\n`) allowed. Pressing enter key will result in the `TextEdit` loosing focus (`response.lost_kb_focus`).
|
||||||
|
///
|
||||||
|
/// Se also [`TextEdit`].
|
||||||
pub fn text_edit_singleline(&mut self, text: &mut String) -> Response {
|
pub fn text_edit_singleline(&mut self, text: &mut String) -> Response {
|
||||||
self.add(TextEdit::singleline(text))
|
self.add(TextEdit::singleline(text))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `TextEdit` for multiple lines. Pressing enter key will create a new line.
|
/// A `TextEdit` for multiple lines. Pressing enter key will create a new line.
|
||||||
|
///
|
||||||
|
/// Se also [`TextEdit`].
|
||||||
pub fn text_edit_multiline(&mut self, text: &mut String) -> Response {
|
pub fn text_edit_multiline(&mut self, text: &mut String) -> Response {
|
||||||
self.add(TextEdit::multiline(text))
|
self.add(TextEdit::multiline(text))
|
||||||
}
|
}
|
||||||
|
@ -847,6 +857,8 @@ impl Ui {
|
||||||
/// Usage: `if ui.button("Click me").clicked() { … }`
|
/// Usage: `if ui.button("Click me").clicked() { … }`
|
||||||
///
|
///
|
||||||
/// Shortcut for `add(Button::new(text))`
|
/// Shortcut for `add(Button::new(text))`
|
||||||
|
///
|
||||||
|
/// Se also [`Button`].
|
||||||
#[must_use = "You should check if the user clicked this with `if ui.button(…).clicked() { … } "]
|
#[must_use = "You should check if the user clicked this with `if ui.button(…).clicked() { … } "]
|
||||||
pub fn button(&mut self, text: impl Into<String>) -> Response {
|
pub fn button(&mut self, text: impl Into<String>) -> Response {
|
||||||
self.add(Button::new(text))
|
self.add(Button::new(text))
|
||||||
|
@ -867,14 +879,14 @@ impl Ui {
|
||||||
self.add(Checkbox::new(checked, text))
|
self.add(Checkbox::new(checked, text))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show a radio button.
|
/// Show a [`RadioButton`].
|
||||||
/// Often you want to use `ui.radio_value` instead.
|
/// Often you want to use [`Self::radio_value`] instead.
|
||||||
#[must_use = "You should check if the user clicked this with `if ui.radio(…).clicked() { … } "]
|
#[must_use = "You should check if the user clicked this with `if ui.radio(…).clicked() { … } "]
|
||||||
pub fn radio(&mut self, selected: bool, text: impl Into<String>) -> Response {
|
pub fn radio(&mut self, selected: bool, text: impl Into<String>) -> Response {
|
||||||
self.add(RadioButton::new(selected, text))
|
self.add(RadioButton::new(selected, text))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show a radio button. It is selected if `*current_value == selected_value`.
|
/// Show a [`RadioButton`]. It is selected if `*current_value == selected_value`.
|
||||||
/// If clicked, `selected_value` is assigned to `*current_value`.
|
/// If clicked, `selected_value` is assigned to `*current_value`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -906,6 +918,8 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show a label which can be selected or not.
|
/// Show a label which can be selected or not.
|
||||||
|
///
|
||||||
|
/// Se also [`SelectableLabel`].
|
||||||
#[must_use = "You should check if the user clicked this with `if ui.selectable_label(…).clicked() { … } "]
|
#[must_use = "You should check if the user clicked this with `if ui.selectable_label(…).clicked() { … } "]
|
||||||
pub fn selectable_label(&mut self, checked: bool, text: impl Into<String>) -> Response {
|
pub fn selectable_label(&mut self, checked: bool, text: impl Into<String>) -> Response {
|
||||||
self.add(SelectableLabel::new(checked, text))
|
self.add(SelectableLabel::new(checked, text))
|
||||||
|
@ -915,6 +929,8 @@ impl Ui {
|
||||||
/// If clicked, `selected_value` is assigned to `*current_value`.
|
/// If clicked, `selected_value` is assigned to `*current_value`.
|
||||||
///
|
///
|
||||||
/// Example: `ui.selectable_value(&mut my_enum, Enum::Alternative, "Alternative")`.
|
/// Example: `ui.selectable_value(&mut my_enum, Enum::Alternative, "Alternative")`.
|
||||||
|
///
|
||||||
|
/// Se also [`SelectableLabel`].
|
||||||
pub fn selectable_value<Value: PartialEq>(
|
pub fn selectable_value<Value: PartialEq>(
|
||||||
&mut self,
|
&mut self,
|
||||||
current_value: &mut Value,
|
current_value: &mut Value,
|
||||||
|
@ -929,7 +945,7 @@ impl Ui {
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shortcut for `add(Separator::new())`
|
/// Shortcut for `add(Separator::new())` (see [`Separator`]).
|
||||||
pub fn separator(&mut self) -> Response {
|
pub fn separator(&mut self) -> Response {
|
||||||
self.add(Separator::new())
|
self.add(Separator::new())
|
||||||
}
|
}
|
||||||
|
@ -974,6 +990,8 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show an image here with the given size.
|
/// Show an image here with the given size.
|
||||||
|
///
|
||||||
|
/// See also [`Image`].
|
||||||
pub fn image(&mut self, texture_id: TextureId, size: impl Into<Vec2>) -> Response {
|
pub fn image(&mut self, texture_id: TextureId, size: impl Into<Vec2>) -> Response {
|
||||||
self.add(Image::new(texture_id, size))
|
self.add(Image::new(texture_id, size))
|
||||||
}
|
}
|
||||||
|
@ -1102,7 +1120,7 @@ impl Ui {
|
||||||
self.allocate_ui(desired_size, add_contents).response.rect
|
self.allocate_ui(desired_size, add_contents).response.rect
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `CollapsingHeader` that starts out collapsed.
|
/// A [`CollapsingHeader`] that starts out collapsed.
|
||||||
pub fn collapsing<R>(
|
pub fn collapsing<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
heading: impl Into<String>,
|
heading: impl Into<String>,
|
||||||
|
@ -1111,7 +1129,7 @@ impl Ui {
|
||||||
CollapsingHeader::new(heading).show(self, add_contents)
|
CollapsingHeader::new(heading).show(self, add_contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a child ui which is indented to the right
|
/// Create a child ui which is indented to the right.
|
||||||
pub fn indent<R>(
|
pub fn indent<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
id_source: impl Hash,
|
id_source: impl Hash,
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// An widget to show an image of a given size.
|
/// An widget to show an image of a given size.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # let ui = &mut egui::Ui::__test();
|
||||||
|
/// # let my_texture_id = egui::TextureId::User(0);
|
||||||
|
/// ui.add(egui::Image::new(my_texture_id, [640.0, 480.0]));
|
||||||
|
///
|
||||||
|
/// // Shorter version:
|
||||||
|
/// ui.image(my_texture_id, [640.0, 480.0]);
|
||||||
|
/// ```
|
||||||
#[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 {
|
||||||
|
|
|
@ -76,6 +76,12 @@ pub trait App {
|
||||||
fn load(&mut self, _storage: &dyn Storage) {}
|
fn load(&mut self, _storage: &dyn Storage) {}
|
||||||
|
|
||||||
/// Called on shutdown, and perhaps at regular intervals. Allows you to save state.
|
/// Called on shutdown, and perhaps at regular intervals. Allows you to save state.
|
||||||
|
///
|
||||||
|
/// On web the states is stored to "Local Storage".
|
||||||
|
/// On native the path is picked using [`directories_next::ProjectDirs`](https://docs.rs/directories-next/latest/directories_next/struct.ProjectDirs.html) which is:
|
||||||
|
/// * Linux: `/home/UserName/.config/appname`
|
||||||
|
/// * macOS: `/Users/UserName/Library/Application Support/appname`
|
||||||
|
/// * Windows: `C:\Users\UserName\AppData\Roaming\appname`
|
||||||
fn save(&mut self, _storage: &mut dyn Storage) {}
|
fn save(&mut self, _storage: &mut dyn Storage) {}
|
||||||
|
|
||||||
/// Called once on shutdown (before or after `save()`)
|
/// Called once on shutdown (before or after `save()`)
|
||||||
|
|
Loading…
Reference in a new issue