Highlight submenu buttons when hovered and open (#3780)

Submenu buttons in menues now properly highlight when hovered and when
opened.

…plus a bunch of other cleanup
This commit is contained in:
Emil Ernerfeldt 2024-01-07 22:08:32 +01:00 committed by GitHub
parent 327f599407
commit 8c30e8c5f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 62 additions and 57 deletions

View File

@ -1218,7 +1218,7 @@ impl GlutinWindowContext {
}
fn initialize_or_update_viewport<'vp>(
egu_ctx: &'_ egui::Context,
egu_ctx: &egui::Context,
viewports: &'vp mut ViewportIdMap<Viewport>,
ids: ViewportIdPair,
class: ViewportClass,

View File

@ -502,7 +502,7 @@ impl<'open> Window<'open> {
// END FRAME --------------------------------
if let Some(title_bar) = title_bar {
if on_top {
if on_top && area_content_ui.visuals().window_highlight_topmost {
let rect = Rect::from_min_size(
outer_rect.min,
Vec2 {
@ -515,7 +515,7 @@ impl<'open> Window<'open> {
round.se = 0.0;
round.sw = 0.0;
}
let header_color = area_content_ui.visuals().widgets.hovered.bg_fill;
let header_color = area_content_ui.visuals().widgets.open.weak_bg_fill;
area_content_ui.painter().set(
*where_to_put_header_background,

View File

@ -440,11 +440,11 @@ impl SubMenuButton {
fn visuals<'a>(
ui: &'a Ui,
response: &'_ Response,
menu_state: &'_ MenuState,
response: &Response,
menu_state: &MenuState,
sub_id: Id,
) -> &'a WidgetVisuals {
if menu_state.is_open(sub_id) {
if menu_state.is_open(sub_id) && !response.hovered() {
&ui.style().visuals.widgets.open
} else {
ui.style().interact(response)
@ -528,15 +528,15 @@ impl SubMenu {
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<Option<R>> {
let sub_id = ui.id().with(self.button.index);
let button = self.button.show(ui, &self.parent_state.read(), sub_id);
let response = self.button.show(ui, &self.parent_state.read(), sub_id);
self.parent_state
.write()
.submenu_button_interaction(ui, sub_id, &button);
.submenu_button_interaction(ui, sub_id, &response);
let inner = self
.parent_state
.write()
.show_submenu(ui.ctx(), sub_id, add_contents);
InnerResponse::new(inner, button)
InnerResponse::new(inner, response)
}
}

View File

@ -779,6 +779,9 @@ pub struct Visuals {
pub window_fill: Color32,
pub window_stroke: Stroke,
/// Highlight the topmost window.
pub window_highlight_topmost: bool,
pub menu_rounding: Rounding,
/// Panel background color
@ -1130,6 +1133,7 @@ impl Visuals {
window_shadow: Shadow::big_dark(),
window_fill: Color32::from_gray(27),
window_stroke: Stroke::new(1.0, Color32::from_gray(60)),
window_highlight_topmost: true,
menu_rounding: Rounding::same(6.0),
@ -1247,7 +1251,7 @@ impl Widgets {
expansion: 1.0,
},
open: WidgetVisuals {
weak_bg_fill: Color32::from_gray(27),
weak_bg_fill: Color32::from_gray(45),
bg_fill: Color32::from_gray(27),
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)),
fg_stroke: Stroke::new(1.0, Color32::from_gray(210)),
@ -1694,6 +1698,7 @@ impl Visuals {
window_shadow,
window_fill,
window_stroke,
window_highlight_topmost,
menu_rounding,
@ -1736,6 +1741,7 @@ impl Visuals {
stroke_ui(ui, window_stroke, "Outline");
rounding_ui(ui, window_rounding);
shadow_ui(ui, window_shadow, "Shadow");
ui.checkbox(window_highlight_topmost, "Highlight topmost Window");
});
ui.collapsing("Menus and popups", |ui| {

View File

@ -79,7 +79,7 @@ impl<'a> Widget for DatePickerButton<'a> {
fn ui(self, ui: &mut Ui) -> egui::Response {
let id = ui.make_persistent_id(self.id_source);
let mut button_state = ui
.memory_mut(|mem| mem.data.get_persisted::<DatePickerButtonState>(id))
.data_mut(|data| data.get_persisted::<DatePickerButtonState>(id))
.unwrap_or_default();
let mut text = if self.show_icon {
@ -98,7 +98,7 @@ impl<'a> Widget for DatePickerButton<'a> {
let mut button_response = ui.add(button);
if button_response.clicked() {
button_state.picker_visible = true;
ui.memory_mut(|mem| mem.data.insert_persisted(id, button_state.clone()));
ui.data_mut(|data| data.insert_persisted(id, button_state.clone()));
}
if button_state.picker_visible {
@ -152,7 +152,7 @@ impl<'a> Widget for DatePickerButton<'a> {
&& (ui.input(|i| i.key_pressed(Key::Escape)) || area_response.clicked_elsewhere())
{
button_state.picker_visible = false;
ui.memory_mut(|mem| mem.data.insert_persisted(id, button_state));
ui.data_mut(|data| data.insert_persisted(id, button_state));
}
}

View File

@ -41,14 +41,14 @@ impl<'a> DatePickerPopup<'a> {
let id = ui.make_persistent_id("date_picker");
let today = chrono::offset::Utc::now().date_naive();
let mut popup_state = ui
.memory_mut(|mem| mem.data.get_persisted::<DatePickerPopupState>(id))
.data_mut(|data| data.get_persisted::<DatePickerPopupState>(id))
.unwrap_or_default();
if !popup_state.setup {
popup_state.year = self.selection.year();
popup_state.month = self.selection.month();
popup_state.day = self.selection.day();
popup_state.setup = true;
ui.memory_mut(|mem| mem.data.insert_persisted(id, popup_state.clone()));
ui.data_mut(|data| data.insert_persisted(id, popup_state.clone()));
}
let weeks = month_data(popup_state.year, popup_state.month);
@ -161,8 +161,8 @@ impl<'a> DatePickerPopup<'a> {
popup_state.year -= 1;
popup_state.day =
popup_state.day.min(popup_state.last_day_of_month());
ui.memory_mut(|mem| {
mem.data.insert_persisted(id, popup_state.clone());
ui.data_mut(|data| {
data.insert_persisted(id, popup_state.clone());
});
}
});
@ -181,8 +181,8 @@ impl<'a> DatePickerPopup<'a> {
}
popup_state.day =
popup_state.day.min(popup_state.last_day_of_month());
ui.memory_mut(|mem| {
mem.data.insert_persisted(id, popup_state.clone());
ui.data_mut(|data| {
data.insert_persisted(id, popup_state.clone());
});
}
});
@ -199,8 +199,8 @@ impl<'a> DatePickerPopup<'a> {
}
popup_state.day = popup_state.last_day_of_month();
}
ui.memory_mut(|mem| {
mem.data.insert_persisted(id, popup_state.clone());
ui.data_mut(|data| {
data.insert_persisted(id, popup_state.clone());
});
}
});
@ -217,8 +217,8 @@ impl<'a> DatePickerPopup<'a> {
popup_state.year += 1;
}
}
ui.memory_mut(|mem| {
mem.data.insert_persisted(id, popup_state.clone());
ui.data_mut(|data| {
data.insert_persisted(id, popup_state.clone());
});
}
});
@ -233,8 +233,8 @@ impl<'a> DatePickerPopup<'a> {
}
popup_state.day =
popup_state.day.min(popup_state.last_day_of_month());
ui.memory_mut(|mem| {
mem.data.insert_persisted(id, popup_state.clone());
ui.data_mut(|data| {
data.insert_persisted(id, popup_state.clone());
});
}
});
@ -245,8 +245,8 @@ impl<'a> DatePickerPopup<'a> {
popup_state.year += 1;
popup_state.day =
popup_state.day.min(popup_state.last_day_of_month());
ui.memory_mut(|mem| {
mem.data.insert_persisted(id, popup_state.clone());
ui.data_mut(|data| {
data.insert_persisted(id, popup_state.clone());
});
}
});
@ -355,8 +355,8 @@ impl<'a> DatePickerPopup<'a> {
popup_state.year = day.year();
popup_state.month = day.month();
popup_state.day = day.day();
ui.memory_mut(|mem| {
mem.data.insert_persisted(
ui.data_mut(|data| {
data.insert_persisted(
id,
popup_state.clone(),
);
@ -402,10 +402,9 @@ impl<'a> DatePickerPopup<'a> {
if close {
popup_state.setup = false;
ui.memory_mut(|mem| {
mem.data.insert_persisted(id, popup_state);
mem.data
.get_persisted_mut_or_default::<DatePickerButtonState>(self.button_id)
ui.data_mut(|data| {
data.insert_persisted(id, popup_state);
data.get_persisted_mut_or_default::<DatePickerButtonState>(self.button_id)
.picker_visible = false;
});
}

View File

@ -18,6 +18,7 @@ impl ImageCrateLoader {
}
fn is_supported_uri(uri: &str) -> bool {
// TODO(emilk): use https://github.com/image-rs/image/pull/2038 when new `image` crate is released.
let Some(ext) = Path::new(uri).extension().and_then(|ext| ext.to_str()) else {
// `true` because if there's no extension, assume that we support it
return true;
@ -27,6 +28,7 @@ fn is_supported_uri(uri: &str) -> bool {
}
fn is_unsupported_mime(mime: &str) -> bool {
// TODO(emilk): use https://github.com/image-rs/image/pull/2038 when new `image` crate is released.
mime.contains("svg")
}

View File

@ -1087,7 +1087,7 @@ impl<'a> TableBody<'a> {
if is_row_hovered {
self.layout
.ui
.memory_mut(|w| w.data.insert_temp(self.hovered_row_index_id, row_index));
.data_mut(|data| data.insert_temp(self.hovered_row_index_id, row_index));
}
}
}

View File

@ -854,9 +854,8 @@ impl Plot {
ui.ctx().check_for_id_clash(plot_id, rect, "Plot");
let memory = if reset {
if let Some((name, _)) = linked_axes.as_ref() {
ui.memory_mut(|memory| {
let link_groups: &mut BoundsLinkGroups =
memory.data.get_temp_mut_or_default(Id::NULL);
ui.data_mut(|data| {
let link_groups: &mut BoundsLinkGroups = data.get_temp_mut_or_default(Id::NULL);
link_groups.0.remove(name);
});
};
@ -941,8 +940,8 @@ impl Plot {
// Find the cursors from other plots we need to draw
let draw_cursors: Vec<Cursor> = if let Some((id, _)) = linked_cursors.as_ref() {
ui.memory_mut(|memory| {
let frames: &mut CursorLinkGroups = memory.data.get_temp_mut_or_default(Id::NULL);
ui.data_mut(|data| {
let frames: &mut CursorLinkGroups = data.get_temp_mut_or_default(Id::NULL);
let cursors = frames.0.entry(*id).or_default();
// Look for our previous frame
@ -969,9 +968,8 @@ impl Plot {
// Transfer the bounds from a link group.
if let Some((id, axes)) = linked_axes.as_ref() {
ui.memory_mut(|memory| {
let link_groups: &mut BoundsLinkGroups =
memory.data.get_temp_mut_or_default(Id::NULL);
ui.data_mut(|data| {
let link_groups: &mut BoundsLinkGroups = data.get_temp_mut_or_default(Id::NULL);
if let Some(linked_bounds) = link_groups.0.get(id) {
if axes.x {
bounds.set_x(&linked_bounds.bounds);
@ -1218,8 +1216,8 @@ impl Plot {
if let Some((id, _)) = linked_cursors.as_ref() {
// Push the frame we just drew to the list of frames
ui.memory_mut(|memory| {
let frames: &mut CursorLinkGroups = memory.data.get_temp_mut_or_default(Id::NULL);
ui.data_mut(|data| {
let frames: &mut CursorLinkGroups = data.get_temp_mut_or_default(Id::NULL);
let cursors = frames.0.entry(*id).or_default();
cursors.push(PlotFrameCursors {
id: plot_id,
@ -1230,9 +1228,8 @@ impl Plot {
if let Some((id, _)) = linked_axes.as_ref() {
// Save the linked bounds.
ui.memory_mut(|memory| {
let link_groups: &mut BoundsLinkGroups =
memory.data.get_temp_mut_or_default(Id::NULL);
ui.data_mut(|data| {
let link_groups: &mut BoundsLinkGroups = data.get_temp_mut_or_default(Id::NULL);
link_groups.0.insert(
*id,
LinkedBounds {

View File

@ -109,11 +109,11 @@ where
/// `(time, value)` pairs
/// Time difference between values can be zero, but never negative.
// TODO(emilk): impl IntoIter
pub fn iter(&'_ self) -> impl ExactSizeIterator<Item = (f64, T)> + '_ {
pub fn iter(&self) -> impl ExactSizeIterator<Item = (f64, T)> + '_ {
self.values.iter().map(|(time, value)| (*time, *value))
}
pub fn values(&'_ self) -> impl ExactSizeIterator<Item = T> + '_ {
pub fn values(&self) -> impl ExactSizeIterator<Item = T> + '_ {
self.values.iter().map(|(_time, value)| *value)
}

View File

@ -290,10 +290,7 @@ impl FontImage {
///
/// If you are having problems with text looking skinny and pixelated, try using a low gamma, e.g. `0.4`.
#[inline]
pub fn srgba_pixels(
&'_ self,
gamma: Option<f32>,
) -> impl ExactSizeIterator<Item = Color32> + '_ {
pub fn srgba_pixels(&self, gamma: Option<f32>) -> impl ExactSizeIterator<Item = Color32> + '_ {
let gamma = gamma.unwrap_or(0.55); // TODO(emilk): this default coverage gamma is a magic constant, chosen by eye. I don't even know why we need it.
self.pixels.iter().map(move |coverage| {
let alpha = coverage.powf(gamma);

View File

@ -7,6 +7,7 @@ The result can be copy-pasted into CHANGELOG.md,
though it often needs some manual editing too.
"""
import argparse
import multiprocessing
import re
import sys
@ -19,7 +20,6 @@ from tqdm import tqdm
OWNER = "emilk"
REPO = "egui"
COMMIT_RANGE = "latest..HEAD"
INCLUDE_LABELS = False # It adds quite a bit of visual noise
OFFICIAL_DEVS = [
"emilk",
@ -118,8 +118,12 @@ def print_section(crate: str, items: List[str]) -> None:
def main() -> None:
parser = argparse.ArgumentParser(description="Generate a changelog.")
parser.add_argument("--commit-range", help="e.g. 0.24.0..HEAD")
args = parser.parse_args()
repo = Repo(".")
commits = list(repo.iter_commits(COMMIT_RANGE))
commits = list(repo.iter_commits(args.commit_range))
commits.reverse() # Most recent last
commit_infos = list(map(get_commit_info, commits))
@ -191,7 +195,7 @@ def main() -> None:
unsorted_prs.append(summary)
print()
print(f"Full diff at https://github.com/emilk/egui/compare/{COMMIT_RANGE}")
print(f"Full diff at https://github.com/emilk/egui/compare/{args.commit_range}")
print()
for crate in crate_names:
if crate in sections:

View File

@ -7,4 +7,4 @@ cd "$script_path/.."
rustup target add wasm32-unknown-unknown
# For generating JS bindings:
cargo install wasm-bindgen-cli --version 0.2.89
cargo install --quiet wasm-bindgen-cli --version 0.2.89