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:
parent
327f599407
commit
8c30e8c5f7
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue