Skip to content

Commit

Permalink
Apply context menu to Response
Browse files Browse the repository at this point in the history
  • Loading branch information
mankinskin committed Jul 7, 2021
1 parent 330fb62 commit 701baf9
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 78 deletions.
4 changes: 2 additions & 2 deletions egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ impl CtxRef {
}


pub(crate) fn show_ui_context_menu(&self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) {
self.context_menu_system().ui_context_menu(ui, add_contents)
pub(crate) fn show_ui_context_menu(&self, response: &Response, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) {
self.context_menu_system().ui_context_menu(response, add_contents)
}
}

Expand Down
50 changes: 30 additions & 20 deletions egui/src/context_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,23 @@ pub struct ContextMenuSystem {
context_menu: Option<ContextMenuRoot>,
}
impl ContextMenuSystem {
fn response(&mut self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) -> MenuResponse {
if let Some(context_menu) = &mut self.context_menu {
if context_menu.ui_id == ui.id() {
let response = context_menu.show(ui.ctx(), add_contents);
context_menu.rect = response.rect;

if context_menu.response.is_close() {
return MenuResponse::Close;
}
}
}
let pointer = &ui.input().pointer;
if let Some(pos) = pointer.interact_pos() {
if pointer.any_pressed() {
fn sense_click(&mut self, response: &Response) -> MenuResponse {
let Response {
id,
ctx,
..
} = response;
let pointer = &ctx.input().pointer;
if pointer.any_pressed() {
if let Some(pos) = pointer.interact_pos() {
let mut destroy = false;
let mut in_old_menu = false;
if let Some(context_menu) = &mut self.context_menu {
in_old_menu = context_menu.area_contains(pos);
destroy = context_menu.ui_id == ui.id();
destroy = context_menu.ui_id == *id;
}
let in_ui = ui.rect_contains_pointer(ui.max_rect_finite());
if !in_old_menu {
if in_ui {
if response.hovered() {
if pointer.button_down(PointerButton::Secondary) {
// todo: adapt to context
return MenuResponse::Create(pos);
Expand All @@ -49,15 +43,31 @@ impl ContextMenuSystem {
}
MenuResponse::Stay
}
pub fn ui_context_menu(&mut self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) {
match self.response(ui, add_contents) {
fn show(&mut self, response: &Response, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) -> MenuResponse {
if let Some(context_menu) = &mut self.context_menu {
if context_menu.ui_id == response.id {
let response = context_menu.show(&response.ctx, add_contents);
context_menu.rect = response.rect;

if context_menu.response.is_close() {
return MenuResponse::Close;
}
}
}
MenuResponse::Stay
}
pub fn ui_context_menu(&mut self, response: &Response, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) {
match self.sense_click(response) {
MenuResponse::Create(pos) => {
self.context_menu = Some(ContextMenuRoot::new(pos, ui.id()));
self.context_menu = Some(ContextMenuRoot::new(pos, response.id));
},
MenuResponse::Close => {
self.context_menu = None
},
MenuResponse::Stay => {}
};
if let MenuResponse::Close = self.show(response, add_contents) {
self.context_menu = None
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions egui/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,11 @@ impl Response {
self.ctx.output().events.push(event);
}
}

pub fn context_menu(&self, add_contents: impl FnOnce(&mut Ui, &mut super::context_menu::MenuState)) -> &Self {
self.ctx.show_ui_context_menu(&self, add_contents);
self
}
}

impl Response {
Expand Down
3 changes: 0 additions & 3 deletions egui/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,6 @@ impl Ui {
self.painter.set_clip_rect(clip_rect);
}

pub fn context_menu(&mut self, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) {
self.ctx().clone().show_ui_context_menu(self, add_contents)
}
}

// ------------------------------------------------------------------------
Expand Down
23 changes: 16 additions & 7 deletions egui_demo_lib/src/apps/demo/drag_and_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,6 @@ impl super::View for DragAndDropDemo {
let mut source_col_row = None;
let mut drop_col = None;
ui.columns(self.columns.len(), |uis| {
uis[0].context_menu(|ui, menu_state| {
if ui.button("New Item...").clicked() {
self.columns[0].push("New Item".to_string());
menu_state.close();
}
});
for (col_idx, column) in self.columns.clone().into_iter().enumerate() {
let ui = &mut uis[col_idx];
let can_accept_what_is_being_dragged = true; // We accept anything being dragged (for now) ¯\_(ツ)_/¯
Expand All @@ -133,7 +127,13 @@ impl super::View for DragAndDropDemo {
for (row_idx, item) in column.iter().enumerate() {
let item_id = Id::new("item").with(col_idx).with(row_idx);
drag_source(ui, item_id, |ui| {
ui.label(item);
ui.add(Label::new(item).sense(Sense::click()))
.context_menu(|ui, menu_state| {
if ui.button("Remove...").clicked() {
self.columns[col_idx].remove(row_idx);
menu_state.close();
}
});
});

if ui.memory().is_being_dragged(item_id) {
Expand All @@ -143,6 +143,15 @@ impl super::View for DragAndDropDemo {
})
.response;

if col_idx == 0 {
response.context_menu(|ui, menu_state| {
if ui.button("New Item...").clicked() {
self.columns[0].push("New Item".to_string());
menu_state.close();
}
});
}

let is_being_dragged = ui.memory().is_anything_being_dragged();
if is_being_dragged && can_accept_what_is_being_dragged && response.hovered() {
drop_col = Some(col_idx);
Expand Down
6 changes: 2 additions & 4 deletions egui_demo_lib/src/apps/demo/widget_gallery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ impl WidgetGallery {
ui.end_row();

ui.add(doc_link_label("Plot", "plot"));
ui.scope(|ui| {
ui.context_menu(|ui, menu_state| {
ui.add(example_plot(plot))
.context_menu(|ui, menu_state| {
if ui.button("Sin").clicked() {
*plot = Plot::Sin;
menu_state.close();
Expand All @@ -236,8 +236,6 @@ impl WidgetGallery {
menu_state.close();
}
});
ui.add(example_plot(plot));
});

ui.end_row();

Expand Down
13 changes: 7 additions & 6 deletions egui_demo_lib/src/apps/demo/window_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,13 @@ impl super::View for WindowOptions {
ui.horizontal(|ui| {
ui.label("title:");
ui.text_edit_singleline(title);
ui.context_menu(|ui, menu_state| {
if ui.button("Clear..").clicked() {
*title = String::new();
menu_state.close();
}
});
})
.response
.context_menu(|ui, menu_state| {
if ui.button("Clear..").clicked() {
*title = String::new();
menu_state.close();
}
});
ui.checkbox(title_bar, "title_bar");
ui.checkbox(closable, "closable");
Expand Down
55 changes: 26 additions & 29 deletions egui_demo_lib/src/backend_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,40 +103,37 @@ impl BackendPanel {
self.egui_windows.windows(ctx);
}

fn context_menu(&mut self, ui: &mut egui::Ui) {
pub fn context_menu(ui: &mut egui::Ui, menu_state: &mut egui::context_menu::MenuState) {
use egui::context_menu::SubMenu;
ui.context_menu(|ui, menu_state| {
if ui.button("Open...").clicked() {
menu_state.close();
}
SubMenu::new("SubMenu")
.show(ui, menu_state, |ui, menu_state| {
if ui.button("Open...").clicked() {
menu_state.close();
}
SubMenu::new("SubMenu")
.show(ui, menu_state, |ui, menu_state| {
if ui.button("Open...").clicked() {
menu_state.close();
}
let _ = ui.button("Item");
});
let _ = ui.button("Item");
});
SubMenu::new("SubMenu")
.show(ui, menu_state, |ui, _menu_state| {
let _ = ui.button("Item1");
let _ = ui.button("Item2");
let _ = ui.button("Item3");
let _ = ui.button("Item4");
});
let _ = ui.button("Item");
});
if ui.button("Open...").clicked() {
menu_state.close();
}
SubMenu::new("SubMenu")
.show(ui, menu_state, |ui, menu_state| {
if ui.button("Open...").clicked() {
menu_state.close();
}
SubMenu::new("SubMenu")
.show(ui, menu_state, |ui, menu_state| {
if ui.button("Open...").clicked() {
menu_state.close();
}
let _ = ui.button("Item");
});
let _ = ui.button("Item");
});
SubMenu::new("SubMenu")
.show(ui, menu_state, |ui, _menu_state| {
let _ = ui.button("Item1");
let _ = ui.button("Item2");
let _ = ui.button("Item3");
let _ = ui.button("Item4");
});
let _ = ui.button("Item");
}

pub fn ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame<'_>) {
egui::trace!(ui);
self.context_menu(ui);
ui.vertical_centered(|ui| {
ui.heading("💻 Backend");
});
Expand Down
18 changes: 11 additions & 7 deletions egui_demo_lib/src/wrap_app.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::backend_panel::BackendPanel;
/// All the different demo apps.
#[derive(Default)]
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
Expand Down Expand Up @@ -32,7 +33,7 @@ impl Apps {
pub struct WrapApp {
selected_anchor: String,
apps: Apps,
backend_panel: super::backend_panel::BackendPanel,
backend_panel: BackendPanel,
}

impl epi::App for WrapApp {
Expand Down Expand Up @@ -92,7 +93,9 @@ impl epi::App for WrapApp {
if self.backend_panel.open || ctx.memory().everything_is_visible() {
egui::SidePanel::left("backend_panel").show(ctx, |ui| {
self.backend_panel.ui(ui, frame);
});
})
.response
.context_menu(|ui, menu_state| BackendPanel::context_menu(ui, menu_state));
}

for (anchor, app) in self.apps.iter_mut() {
Expand All @@ -110,11 +113,6 @@ impl WrapApp {
// A menu-bar is a horizontal layout with some special styles applied.
// egui::menu::bar(ui, |ui| {
ui.horizontal_wrapped(|ui| {
ui.context_menu(|ui, _menu_state| {
if ui.button("Print something").clicked() {
println!("something");
}
});
dark_light_mode_switch(ui);

ui.checkbox(&mut self.backend_panel.open, "💻 Backend");
Expand Down Expand Up @@ -147,6 +145,12 @@ impl WrapApp {

egui::warn_if_debug_build(ui);
});
})
.response
.context_menu(|ui, _menu_state| {
if ui.button("Print something").clicked() {
println!("something");
}
});
}
}
Expand Down

0 comments on commit 701baf9

Please sign in to comment.