Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widget hover effect #935

Merged
merged 7 commits into from
Jan 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ arrow2_convert = { git = "https://github.com/rerun-io/arrow2-convert", rev = "7e
# arrow2 = { path = "../arrow2" }
# arrow2_convert = { path = "../arrow2-convert/arrow2_convert" }

# 2023-01-27 - dragvalue/sliders use proportional font
ecolor = { git = "https://github.com/emilk/egui", rev = "e7c0547e23aa6139c51ecdd4bb1dc346bbcac22c" }
eframe = { git = "https://github.com/emilk/egui", rev = "e7c0547e23aa6139c51ecdd4bb1dc346bbcac22c" }
egui = { git = "https://github.com/emilk/egui", rev = "e7c0547e23aa6139c51ecdd4bb1dc346bbcac22c" }
egui_extras = { git = "https://github.com/emilk/egui", rev = "e7c0547e23aa6139c51ecdd4bb1dc346bbcac22c" }
egui-wgpu = { git = "https://github.com/emilk/egui", rev = "e7c0547e23aa6139c51ecdd4bb1dc346bbcac22c" }
emath = { git = "https://github.com/emilk/egui", rev = "e7c0547e23aa6139c51ecdd4bb1dc346bbcac22c" }
epaint = { git = "https://github.com/emilk/egui", rev = "e7c0547e23aa6139c51ecdd4bb1dc346bbcac22c" }
# 2023-01-27 - highlight widgets
ecolor = { git = "https://github.com/emilk/egui", rev = "f222ee044edf8beebfaf5dd7be15c9f318f20886" }
eframe = { git = "https://github.com/emilk/egui", rev = "f222ee044edf8beebfaf5dd7be15c9f318f20886" }
egui = { git = "https://github.com/emilk/egui", rev = "f222ee044edf8beebfaf5dd7be15c9f318f20886" }
egui_extras = { git = "https://github.com/emilk/egui", rev = "f222ee044edf8beebfaf5dd7be15c9f318f20886" }
egui-wgpu = { git = "https://github.com/emilk/egui", rev = "f222ee044edf8beebfaf5dd7be15c9f318f20886" }
emath = { git = "https://github.com/emilk/egui", rev = "f222ee044edf8beebfaf5dd7be15c9f318f20886" }
epaint = { git = "https://github.com/emilk/egui", rev = "f222ee044edf8beebfaf5dd7be15c9f318f20886" }
# ecolor = { path = "../../egui/crates/ecolor" }
# eframe = { path = "../../egui/crates/eframe" }
# egui = { path = "../../egui/crates/egui" }
Expand Down
37 changes: 37 additions & 0 deletions crates/re_viewer/src/misc/selection_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,43 @@ impl SelectionState {
self.history.selection_ui(ui, blueprint)
}

pub fn highlight_for_ui_element(&self, test: &Selection) -> HoverHighlight {
let hovered = self
.hovered_previous_frame
.iter()
.any(|current| match current {
Selection::MsgId(_)
| Selection::DataPath(_)
| Selection::SpaceView(_)
| Selection::DataBlueprintGroup(_, _) => current == test,

Selection::Instance(current_space_view_id, current_instance_id) => {
if let Selection::Instance(test_space_view_id, test_instance_id) = test {
// For both space view id and instance index we want to be inclusive,
// but if both are set to Some, and set to different, then we count that
// as a miss.
fn either_none_or_same<T: PartialEq>(a: &Option<T>, b: &Option<T>) -> bool {
a.is_none() || b.is_none() || a == b
}

current_instance_id.obj_path == test_instance_id.obj_path
&& either_none_or_same(
&current_instance_id.instance_index,
&test_instance_id.instance_index,
)
&& either_none_or_same(current_space_view_id, test_space_view_id)
} else {
false
}
}
});
if hovered {
HoverHighlight::Hovered
} else {
HoverHighlight::None
}
}

pub fn highlights_for_space_view(
&self,
space_view_id: SpaceViewId,
Expand Down
19 changes: 14 additions & 5 deletions crates/re_viewer/src/misc/viewer_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use crate::ui::{
DataBlueprintGroupHandle, Preview, SpaceViewId,
};

use super::selection::{MultiSelection, Selection};
use super::{
selection::{MultiSelection, Selection},
HoverHighlight,
};

/// Common things needed by many parts of the viewer.
pub struct ViewerContext<'a> {
Expand Down Expand Up @@ -34,7 +37,6 @@ pub struct ViewerContext<'a> {
impl<'a> ViewerContext<'a> {
/// Show an [`MsgId`] and make it selectable
pub fn msg_id_button(&mut self, ui: &mut egui::Ui, msg_id: MsgId) -> egui::Response {
// TODO(emilk): common hover-effect
let selection = Selection::MsgId(msg_id);
let response = ui
.selectable_label(self.selection().contains(&selection), msg_id.to_string())
Expand Down Expand Up @@ -100,7 +102,7 @@ impl<'a> ViewerContext<'a> {
Some(_) => "Object Instance",
None => "Object",
};
// TODO(emilk): common hover-effect of all buttons for the same instance_id!

let response = ui
.selectable_label(self.selection().contains(&selection), text)
.on_hover_ui(|ui| {
Expand All @@ -124,7 +126,6 @@ impl<'a> ViewerContext<'a> {
text: impl Into<egui::WidgetText>,
data_path: &DataPath,
) -> egui::Response {
// TODO(emilk): common hover-effect of all buttons for the same data_path!
let selection = Selection::DataPath(data_path.clone());
let response = ui.selectable_label(self.selection().contains(&selection), text);
self.cursor_interact_with_selectable(response, selection)
Expand Down Expand Up @@ -256,14 +257,22 @@ impl<'a> ViewerContext<'a> {
response: egui::Response,
selectable: Selection,
) -> egui::Response {
let is_item_hovered =
self.selection_state().highlight_for_ui_element(&selectable) == HoverHighlight::Hovered;

if response.hovered() {
self.rec_cfg
.selection_state
.set_hovered(std::iter::once(selectable));
}
self.select_hovered_on_click(&response);
// TODO(andreas): How to deal with shift click for selecting ranges?
response

if is_item_hovered {
response.highlight()
} else {
response
}
}

/// Returns the current selection.
Expand Down
20 changes: 13 additions & 7 deletions crates/re_viewer/src/ui/viewport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,28 +620,34 @@ fn blueprint_row_with_visibility_button(

let main_button_rect = main_button_response.rect;

// We check the same rectangle as the main button,
// but we will also catch hovers on the visibility button (if any).
let button_hovered = ui
.interact(main_button_rect, ui.id(), egui::Sense::hover())
.hovered();

if button_hovered {
let visibility_button_changed = visibility_button(ui, enabled, visible).changed();
let visibility_button_changed = if button_hovered {
visibility_button_ui(ui, enabled, visible).changed()
} else {
false
};

// The main button might have been highlighted because what it was referring
// to was hovered somewhere else, and then we also want it highlighted here.
if button_hovered || main_button_response.highlighted() {
// Highlight the row:
let visuals = ui.visuals().widgets.hovered;
let hover_rect = main_button_rect.expand(visuals.expansion);
ui.painter().set(
where_to_add_hover_rect,
egui::Shape::rect_filled(hover_rect, visuals.rounding, visuals.bg_fill),
);

visibility_button_changed
} else {
false
}

visibility_button_changed
}

fn visibility_button(ui: &mut egui::Ui, enabled: bool, visible: &mut bool) -> egui::Response {
fn visibility_button_ui(ui: &mut egui::Ui, enabled: bool, visible: &mut bool) -> egui::Response {
// Just put the button on top of the existing ui:
let mut ui = ui.child_ui(
ui.max_rect(),
Expand Down