From 26206526d643215dcc43b0120b9b47434c88cf5c Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 28 May 2024 14:17:37 +0200 Subject: [PATCH] Hide toolip when opening `ComboBox` drop-down (#4546) - Fixes #4338 https://github.com/emilk/egui/assets/49431240/73ea87a1-41ad-40b1-b451-d6be2b38c7e0 Tested using `example/hello_world` modified to: ```rust #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release #![allow(rustdoc::missing_crate_level_docs)] // it's an example use eframe::egui; fn main() -> Result<(), eframe::Error> { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]), ..Default::default() }; eframe::run_native( "My egui App", options, Box::new(|cc| { // This gives us image support: egui_extras::install_image_loaders(&cc.egui_ctx); Box::::default() }), ) } struct MyApp { name: String, age: u32, } impl Default for MyApp { fn default() -> Self { Self { name: "Arthur".to_owned(), age: 42, } } } impl eframe::App for MyApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("My egui Application"); egui::ComboBox::new("combo", "combo box") .selected_text(&self.name) .show_ui(ui, |ui| { ui.selectable_value(&mut self.name, "Arthur".into(), "Arthur") .on_hover_text("This is Arthur"); ui.selectable_value(&mut self.name, "Ford".into(), "Ford") .on_hover_text("This is Ford"); ui.selectable_value(&mut self.name, "Trillian".into(), "Trillian") .on_hover_text("This is Trillian"); }) .response .on_hover_text("This is a combo box"); }); } } ``` --------- Co-authored-by: Emil Ernerfeldt --- crates/egui/src/containers/combo_box.rs | 12 +++++++++++- crates/egui/src/response.rs | 7 ++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/egui/src/containers/combo_box.rs b/crates/egui/src/containers/combo_box.rs index db5a9e3e8bd..b4c7bbca7d3 100644 --- a/crates/egui/src/containers/combo_box.rs +++ b/crates/egui/src/containers/combo_box.rs @@ -270,6 +270,16 @@ impl ComboBox { } response } + + /// Check if the [`ComboBox`] with the given id has its popup menu currently opened. + pub fn is_open(ctx: &Context, id: Id) -> bool { + ctx.memory(|m| m.is_popup_open(Self::widget_to_popup_id(id))) + } + + /// Convert a [`ComboBox`] id to the id used to store it's popup state. + fn widget_to_popup_id(widget_id: Id) -> Id { + widget_id.with("popup") + } } #[allow(clippy::too_many_arguments)] @@ -282,7 +292,7 @@ fn combo_box_dyn<'c, R>( wrap_mode: Option, (width, height): (Option, Option), ) -> InnerResponse> { - let popup_id = button_id.with("popup"); + let popup_id = ComboBox::widget_to_popup_id(button_id); let is_popup_open = ui.memory(|m| m.is_popup_open(popup_id)); diff --git a/crates/egui/src/response.rs b/crates/egui/src/response.rs index d980bd78eb6..264d53d5983 100644 --- a/crates/egui/src/response.rs +++ b/crates/egui/src/response.rs @@ -2,7 +2,8 @@ use std::{any::Any, sync::Arc}; use crate::{ emath::{Align, Pos2, Rect, Vec2}, - menu, Context, CursorIcon, Id, LayerId, PointerButton, Sense, Ui, WidgetRect, WidgetText, + menu, ComboBox, Context, CursorIcon, Id, LayerId, PointerButton, Sense, Ui, WidgetRect, + WidgetText, }; // ---------------------------------------------------------------------------- @@ -571,6 +572,10 @@ impl Response { return false; } + if ComboBox::is_open(&self.ctx, self.id) { + return false; // Don't cover the open ComboBox with a tooltip + } + if self.enabled { if !self.hovered || !self.ctx.input(|i| i.pointer.has_pointer()) { return false;