Skip to content

Commit

Permalink
Clean up some of the new context menus
Browse files Browse the repository at this point in the history
Follow-up to #543

* Add entry to CHANGELOG.md
* Add entry to contributors in README.md
* Improve documentation
* Simplify demo
  • Loading branch information
emilk committed Oct 26, 2021
1 parent 46fb9ff commit 41f77ba
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 88 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w

## Unreleased

### Added ⭐
* Add context menus: See `Ui::menu_button` and `Response::context_menu` ([#543](https://github.com/emilk/egui/pull/543)).


## 0.15.0 - 2021-10-24 - Syntax highlighting and hscroll

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ Notable contributions by:
* [@EmbersArc](https://github.com/EmbersArc): [Plots](https://github.com/emilk/egui/pulls?q=+is%3Apr+author%3AEmbersArc)
* [@AsmPrgmC3](https://github.com/AsmPrgmC3): [Proper sRGBA blending in `egui_web`](https://github.com/emilk/egui/pull/650)
* [@AlexApps99](https://github.com/AlexApps99): [`egui_glow`](https://github.com/emilk/egui/pull/685)
* [@mankinskin](https://github.com/mankinskin): [Context menus](https://github.com/emilk/egui/pull/543)
* And [many more](https://github.com/emilk/egui/graphs/contributors)

egui is licensed under [MIT](LICENSE-MIT) OR [Apache-2.0](LICENSE-APACHE).
Expand Down
1 change: 1 addition & 0 deletions egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ impl CtxRef {
Self::layer_painter(self, LayerId::debug())
}

/// Respond to secondary clicks (right-clicks) by showing the given menu.
pub(crate) fn show_context_menu(
&self,
response: &Response,
Expand Down
1 change: 1 addition & 0 deletions egui/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ impl MenuRoot {
MenuResponse::Stay => {}
}
}
/// Respond to secondary (right) clicks.
pub fn context_click_interaction(response: &Response, root: &mut MenuRootManager, id: Id) {
let menu_response = Self::context_interaction(response, root, id);
Self::handle_menu_response(root, menu_response);
Expand Down
11 changes: 11 additions & 0 deletions egui/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,17 @@ impl Response {
}
}

/// Response to secondary clicks (right-clicks) by showing the given menu.
///
/// ``` rust
/// # let mut ui = &mut egui::Ui::__test();
/// let response = ui.label("Right-click me!");
/// response.context_menu(|ui|{
/// if ui.button("Close the menu").clicked() {
/// ui.close_menu();
/// }
/// });
/// ```
pub fn context_menu(&self, add_contents: impl FnOnce(&mut Ui)) -> &Self {
self.ctx.show_context_menu(self, add_contents);
self
Expand Down
8 changes: 7 additions & 1 deletion egui/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1737,27 +1737,33 @@ impl Ui {
self.advance_cursor_after_rect(Rect::from_min_size(top_left, size));
result
}

/// Close menu (with submenus), if any.
pub fn close_menu(&mut self) {
if let Some(menu_state) = &mut self.menu_state {
menu_state.write().close();
}
self.menu_state = None;
}

pub(crate) fn get_menu_state(&self) -> Option<Arc<RwLock<MenuState>>> {
self.menu_state.clone()
}

pub(crate) fn set_menu_state(&mut self, menu_state: Option<Arc<RwLock<MenuState>>>) {
self.menu_state = menu_state;
}

#[inline(always)]
/// Create a menu button. Creates a button for a sub-menu when the `Ui` is inside a menu.
///
/// ```
/// # let mut ui = egui::Ui::__test();
/// ui.menu_button("My menu", |ui| {
/// ui.menu_button("My sub-menu", |ui| {
/// ui.label("Item");
/// if ui.button("Close the menu").clicked() {
/// ui.close_menu();
/// }
/// });
/// });
/// ```
Expand Down
169 changes: 82 additions & 87 deletions egui_demo_lib/src/apps/demo/context_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ fn sigmoid(x: f64) -> f64 {
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
pub struct ContextMenus {
title: String,
plot: Plot,
show_axes: [bool; 2],
allow_drag: bool,
Expand All @@ -28,6 +27,87 @@ pub struct ContextMenus {
height: f32,
}

impl Default for ContextMenus {
fn default() -> Self {
Self {
plot: Plot::Sin,
show_axes: [true, true],
allow_drag: true,
allow_zoom: true,
center_x_axis: false,
center_y_axis: false,
width: 400.0,
height: 200.0,
}
}
}

impl super::Demo for ContextMenus {
fn name(&self) -> &'static str {
"☰ Context Menus"
}

fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool) {
use super::View;
egui::Window::new(self.name())
.vscroll(false)
.resizable(false)
.open(open)
.show(ctx, |ui| self.ui(ui));
}
}

impl super::View for ContextMenus {
fn ui(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
ui.menu_button("Click for menu", Self::nested_menus);
ui.button("Right-click for menu")
.context_menu(Self::nested_menus);
});

ui.separator();

ui.label("Right-click plot to edit it!");
ui.horizontal(|ui| {
ui.add(self.example_plot()).context_menu(|ui| {
ui.menu_button("Plot", |ui| {
if ui.radio_value(&mut self.plot, Plot::Sin, "Sin").clicked()
|| ui
.radio_value(&mut self.plot, Plot::Bell, "Gaussian")
.clicked()
|| ui
.radio_value(&mut self.plot, Plot::Sigmoid, "Sigmoid")
.clicked()
{
ui.close_menu();
}
});
egui::Grid::new("button_grid").show(ui, |ui| {
ui.add(
egui::DragValue::new(&mut self.width)
.speed(1.0)
.prefix("Width:"),
);
ui.add(
egui::DragValue::new(&mut self.height)
.speed(1.0)
.prefix("Height:"),
);
ui.end_row();
ui.checkbox(&mut self.show_axes[0], "x-Axis");
ui.checkbox(&mut self.show_axes[1], "y-Axis");
ui.end_row();
if ui.checkbox(&mut self.allow_drag, "Drag").changed()
|| ui.checkbox(&mut self.allow_zoom, "Zoom").changed()
{
ui.close_menu();
}
});
});
});
}
}

impl ContextMenus {
fn example_plot(&self) -> egui::plot::Plot {
use egui::plot::{Line, Value, Values};
Expand All @@ -52,6 +132,7 @@ impl ContextMenus {
.height(self.height)
.data_aspect(1.0)
}

fn nested_menus(ui: &mut egui::Ui) {
if ui.button("Open...").clicked() {
ui.close_menu();
Expand Down Expand Up @@ -86,89 +167,3 @@ impl ContextMenus {
let _ = ui.button("Very long text for this item");
}
}

const DEFAULT_TITLE: &str = "☰ Context Menus";

impl Default for ContextMenus {
fn default() -> Self {
Self {
title: DEFAULT_TITLE.to_owned(),
plot: Plot::Sin,
show_axes: [true, true],
allow_drag: true,
allow_zoom: true,
center_x_axis: false,
center_y_axis: false,
width: 400.0,
height: 200.0,
}
}
}
impl super::Demo for ContextMenus {
fn name(&self) -> &'static str {
DEFAULT_TITLE
}

fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool) {
let Self { title, .. } = self.clone();

use super::View;
let window = egui::Window::new(title)
.id(egui::Id::new("demo_context_menus")) // required since we change the title
.vscroll(false)
.open(open);
window.show(ctx, |ui| self.ui(ui));
}
}

impl super::View for ContextMenus {
fn ui(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| ui.text_edit_singleline(&mut self.title));
ui.horizontal(|ui| {
ui.add(self.example_plot())
.on_hover_text("Right click for options")
.context_menu(|ui| {
ui.menu_button("Plot", |ui| {
if ui.radio_value(&mut self.plot, Plot::Sin, "Sin").clicked()
|| ui
.radio_value(&mut self.plot, Plot::Bell, "Gaussian")
.clicked()
|| ui
.radio_value(&mut self.plot, Plot::Sigmoid, "Sigmoid")
.clicked()
{
ui.close_menu();
}
});
egui::Grid::new("button_grid").show(ui, |ui| {
ui.add(
egui::DragValue::new(&mut self.width)
.speed(1.0)
.prefix("Width:"),
);
ui.add(
egui::DragValue::new(&mut self.height)
.speed(1.0)
.prefix("Height:"),
);
ui.end_row();
ui.checkbox(&mut self.show_axes[0], "x-Axis");
ui.checkbox(&mut self.show_axes[1], "y-Axis");
ui.end_row();
if ui.checkbox(&mut self.allow_drag, "Drag").changed()
|| ui.checkbox(&mut self.allow_zoom, "Zoom").changed()
{
ui.close_menu();
}
});
});
});
ui.label("Right-click plot to edit it!");
ui.separator();
ui.horizontal(|ui| {
ui.menu_button("Click for menu", Self::nested_menus);
ui.button("Right-click for menu")
.context_menu(Self::nested_menus);
});
}
}

0 comments on commit 41f77ba

Please sign in to comment.