Skip to content

Commit 93383b4

Browse files
authored
Styling (#6)
* initial styling impl * make buttons that should be small, small * Runtime depth config and fix device selection ui * comment * Proper runtime depth config updates * switch to Yolo v8 * add comma to label for non open zoo models * split 2d + 3d cam view vertically instead of horizontally
1 parent cd44a4b commit 93383b4

25 files changed

+955
-518
lines changed

crates/re_renderer/shader/generic_skybox.wgsl

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn skybox_light_srgb(dir: Vec3) -> Vec3 {
1818
fn main(in: FragmentInput) -> @location(0) Vec4 {
1919
let camera_dir = camera_ray_direction_from_screenuv(in.texcoord);
2020
// Messing with direction a bit so it looks like in our old three-d based renderer (for easier comparison)
21-
let rgb = skybox_dark_srgb(camera_dir); // TODO(andreas): Allow switching to skybox_light
21+
let rgb = skybox_light_srgb(camera_dir); // TODO(andreas): Allow switching to skybox_light
2222
return Vec4(linear_from_srgb(rgb), 1.0);
2323
//return Vec4(camera_dir, 1.0);
2424
}

crates/re_ui/data/design_tokens.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"Color": {
44
"Surface": {
55
"Default": {
6-
"value": "{Global.Color.Gray.50}",
6+
"value": "{Global.Color.White}",
77
"type": "color",
88
"description": "Background color for most UI surfaces in Rerun"
99
},
@@ -15,7 +15,7 @@
1515
},
1616
"Action": {
1717
"Default": {
18-
"value": "{Global.Color.Gray.200}",
18+
"value": "{Global.Color.White}",
1919
"type": "color",
2020
"description": "Background color for UI elements like buttons and selects"
2121
},
@@ -35,7 +35,7 @@
3535
"description": "Background color for suppressed UI elements, like a select that is currently showing a menu"
3636
},
3737
"Inactive": {
38-
"value": "{Global.Color.Gray.200}",
38+
"value": "{Global.Color.White}",
3939
"type": "color",
4040
"description": "Background color for inactive buttons and such"
4141
}
@@ -1274,7 +1274,7 @@
12741274
"type": "color"
12751275
},
12761276
"Hover": {
1277-
"value": "#c1dcf9",
1277+
"value": "#f6fcfe",
12781278
"type": "color"
12791279
}
12801280
},

crates/re_ui/src/design_tokens.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ pub struct DesignTokens {
1919
pub error_hover_bg_color: egui::Color32,
2020
pub primary_bg_color: egui::Color32,
2121
pub primary_hover_bg_color: egui::Color32,
22+
pub gray_50: egui::Color32,
23+
pub gray_900: egui::Color32,
24+
pub primary_700: egui::Color32,
2225
}
2326

2427
impl DesignTokens {
@@ -107,11 +110,11 @@ fn apply_design_tokens(ctx: &egui::Context) -> DesignTokens {
107110
}
108111

109112
{
110-
// Turn off strokes around buttons:
111-
egui_style.visuals.widgets.inactive.bg_stroke = Default::default();
112-
egui_style.visuals.widgets.hovered.bg_stroke = Default::default();
113-
egui_style.visuals.widgets.active.bg_stroke = Default::default();
114-
egui_style.visuals.widgets.open.bg_stroke = Default::default();
113+
let border_color = get_global_color(&json, "{Global.Color.Gray.200}");
114+
egui_style.visuals.widgets.inactive.bg_stroke = egui::Stroke::new(1.0, border_color);
115+
egui_style.visuals.widgets.hovered.bg_stroke = egui::Stroke::new(1.0, border_color);
116+
egui_style.visuals.widgets.active.bg_stroke = egui::Stroke::new(1.0, border_color);
117+
egui_style.visuals.widgets.open.bg_stroke = egui::Stroke::new(1.0, border_color);
115118
}
116119

117120
{
@@ -156,13 +159,14 @@ fn apply_design_tokens(ctx: &egui::Context) -> DesignTokens {
156159
// Add stripes to grids and tables?
157160
egui_style.visuals.striped = false;
158161
egui_style.visuals.indent_has_left_vline = false;
159-
egui_style.spacing.button_padding = egui::Vec2::new(1.0, 0.0); // Makes the icons in the blueprint panel align
162+
egui_style.spacing.button_padding = egui::Vec2::new(12.0, 4.0); // Makes the icons in the blueprint panel align
160163
egui_style.spacing.indent = 14.0; // From figma
161164

162165
egui_style.debug.show_blocking_widget = false; // turn this on to debug interaction problems
163166

164167
egui_style.spacing.combo_width = 8.0; // minimum width of ComboBox - keep them small, with the down-arrow close.
165168

169+
egui_style.spacing.icon_width = 18.0; // Checkbox width and height
166170
egui_style.spacing.scroll_bar_inner_margin = 2.0;
167171
egui_style.spacing.scroll_bar_width = 6.0;
168172
egui_style.spacing.scroll_bar_outer_margin = 2.0;
@@ -191,6 +195,9 @@ fn apply_design_tokens(ctx: &egui::Context) -> DesignTokens {
191195
error_hover_bg_color: get_global_color(&json, "{Global.Color.Error.300}"),
192196
primary_bg_color: get_global_color(&json, "{Global.Color.Primary.Default}"),
193197
primary_hover_bg_color: get_global_color(&json, "{Global.Color.Primary.500}"),
198+
gray_50: get_global_color(&json, "{Global.Color.Gray.50}"),
199+
gray_900: get_global_color(&json, "{Global.Color.Gray.900}"),
200+
primary_700: get_global_color(&json, "{Global.Color.Primary.700}"),
194201
}
195202
}
196203

crates/re_ui/src/lib.rs

+97
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub use command_palette::CommandPalette;
1414
pub use design_tokens::DesignTokens;
1515
pub use icons::Icon;
1616
pub use static_image_cache::StaticImageCache;
17+
use std::ops::RangeInclusive;
1718
pub use toggle_switch::toggle_switch;
1819

1920
// ---------------------------------------------------------------------------
@@ -128,6 +129,99 @@ impl ReUi {
128129
10.0
129130
}
130131

132+
#[inline]
133+
pub const fn box_width() -> f32 {
134+
139.0
135+
}
136+
137+
#[inline]
138+
pub const fn box_height() -> f32 {
139+
22.0
140+
}
141+
142+
pub fn labeled_combo_box<R>(
143+
&self,
144+
ui: &mut egui::Ui,
145+
label: &str,
146+
selected_text: String,
147+
left_to_right: bool,
148+
menu_contents: impl FnOnce(&mut egui::Ui) -> R,
149+
) {
150+
let align = egui::Align::Center;
151+
let layout = if left_to_right {
152+
egui::Layout::left_to_right(align)
153+
} else {
154+
egui::Layout::right_to_left(align)
155+
};
156+
157+
ui.with_layout(layout, |ui| {
158+
if left_to_right {
159+
ui.label(egui::RichText::new(label).color(self.design_tokens.gray_900));
160+
}
161+
ui.add_sized(
162+
[Self::box_width(), Self::box_height() + 1.0],
163+
|ui: &mut egui::Ui| {
164+
egui::ComboBox::from_id_source(label)
165+
.selected_text(selected_text)
166+
.width(Self::box_width())
167+
.show_ui(ui, menu_contents)
168+
.response
169+
},
170+
);
171+
if !left_to_right {
172+
ui.label(egui::RichText::new(label).color(self.design_tokens.gray_900));
173+
}
174+
});
175+
}
176+
177+
pub fn labeled_checkbox(&self, ui: &mut egui::Ui, label: &str, value: &mut bool) {
178+
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
179+
ui.add_sized(
180+
[Self::box_width(), Self::box_height()],
181+
|ui: &mut egui::Ui| {
182+
ui.with_layout(egui::Layout::left_to_right(egui::Align::Center), |ui| {
183+
ui.checkbox(value, "");
184+
})
185+
.response
186+
},
187+
);
188+
ui.label(egui::RichText::new(label).color(self.design_tokens.gray_900));
189+
});
190+
}
191+
192+
pub fn labeled_dragvalue<Num: egui::emath::Numeric>(
193+
&self,
194+
ui: &mut egui::Ui,
195+
label: &str,
196+
value: &mut Num,
197+
range: RangeInclusive<Num>,
198+
) where
199+
Num: egui::emath::Numeric,
200+
{
201+
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
202+
ui.add_sized(
203+
[Self::box_width(), Self::box_height()],
204+
egui::DragValue::new(value).clamp_range(range),
205+
);
206+
ui.label(egui::RichText::new(label).color(self.design_tokens.gray_900));
207+
});
208+
}
209+
210+
pub fn labeled_toggle_switch(&self, ui: &mut egui::Ui, label: &str, value: &mut bool) {
211+
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
212+
ui.add_sized(
213+
[Self::box_width(), Self::box_height()],
214+
|ui: &mut egui::Ui| {
215+
ui.with_layout(egui::Layout::left_to_right(egui::Align::Min), |ui| {
216+
ui.add(toggle_switch(value));
217+
})
218+
.response
219+
},
220+
);
221+
ui.label(egui::RichText::new(label).color(self.design_tokens.gray_900));
222+
});
223+
}
224+
131225
pub fn top_panel_frame(&self) -> egui::Frame {
132226
let mut frame = egui::Frame {
133227
inner_margin: Self::top_bar_margin(),
@@ -290,6 +384,9 @@ impl ReUi {
290384
let texture_id = image.texture_id(ui.ctx());
291385
// TODO(emilk): change color and size on hover
292386
let tint = ui.visuals().widgets.inactive.fg_stroke.color;
387+
let mut style = ui.style_mut().clone();
388+
style.spacing.button_padding = egui::Vec2::new(2.0, 2.0);
389+
ui.set_style(style);
293390
ui.add(egui::ImageButton::new(texture_id, size_points).tint(tint))
294391
}
295392

crates/re_ui/src/toggle_switch.rs

+40-24
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,55 @@
11
//! Adapted from `egui_demo_lib/src/demo/toggle_switch.rs`
2+
pub fn toggle_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
3+
// Widget code can be broken up in four steps:
4+
// 1. Decide a size for the widget
5+
// 2. Allocate space for it
6+
// 3. Handle interactions with the widget (if any)
7+
// 4. Paint the widget
28

3-
fn toggle_switch_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
4-
let interactive_size = egui::vec2(12.0, ui.spacing().interact_size.y);
5-
let (interact_rect, mut response) =
6-
ui.allocate_exact_size(interactive_size, egui::Sense::click());
7-
let visual_size = egui::vec2(12.0, 8.0); // 12x7 in figma, but 12x8 looks _much_ better in epaint
8-
let visual_rect =
9-
egui::Align2::CENTER_CENTER.align_size_within_rect(visual_size, interact_rect);
9+
// 1. Deciding widget size:
10+
// You can query the `ui` how much space is available,
11+
// but in this example we have a fixed size widget based on the height of a standard button:
12+
let desired_size = ui.spacing().interact_size.y * egui::vec2(2.0, 1.0);
1013

14+
// 2. Allocating space:
15+
// This is where we get a region of the screen assigned.
16+
// We also tell the Ui to sense clicks in the allocated region.
17+
let (rect, mut response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
18+
19+
// 3. Interact: Time to check for clicks!
1120
if response.clicked() {
1221
*on = !*on;
13-
response.mark_changed();
22+
response.mark_changed(); // report back that the value changed
1423
}
24+
25+
// Attach some meta-data to the response which can be used by screen readers:
1526
response.widget_info(|| egui::WidgetInfo::selected(egui::WidgetType::Checkbox, *on, ""));
1627

17-
if ui.is_rect_visible(visual_rect) {
28+
// 4. Paint!
29+
// Make sure we need to paint:
30+
if ui.is_rect_visible(rect) {
31+
// Let's ask for a simple animation from egui.
32+
// egui keeps track of changes in the boolean associated with the id and
33+
// returns an animated value in the 0-1 range for how much "on" we are.
1834
let how_on = ui.ctx().animate_bool(response.id, *on);
19-
let visuals = ui.style().interact(&response);
20-
let expanded_rect = visual_rect.expand(visuals.expansion);
21-
let fg_fill = visuals.bg_fill;
22-
let bg_fill = visuals.text_color();
23-
let rounding = 0.5 * expanded_rect.height();
35+
// We will follow the current style by asking
36+
// "how should something that is being interacted with be painted?".
37+
// This will, for instance, give us different colors when the widget is hovered or clicked.
38+
let visuals = ui.style().interact_selectable(&response, *on);
39+
// All coordinates are in absolute screen coordinates so we use `rect` to place the elements.
40+
let rect = rect.expand(visuals.expansion);
41+
let radius = 0.5 * rect.height();
2442
ui.painter()
25-
.rect(expanded_rect, rounding, bg_fill, egui::Stroke::NONE);
26-
let circle_x = egui::lerp(
27-
(expanded_rect.left() + rounding)..=(expanded_rect.right() - rounding),
28-
how_on,
29-
);
30-
31-
let circle_center = egui::pos2(circle_x, expanded_rect.center().y);
32-
let circle_radius = 2.5 * expanded_rect.height() / visual_size.y;
43+
.rect(rect, radius, visuals.bg_fill, visuals.bg_stroke);
44+
// Paint the circle, animating it from left to right with `how_on`:
45+
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
46+
let center = egui::pos2(circle_x, rect.center().y);
3347
ui.painter()
34-
.circle(circle_center, circle_radius, fg_fill, egui::Stroke::NONE);
48+
.circle(center, 0.75 * radius, visuals.bg_fill, visuals.fg_stroke);
3549
}
3650

51+
// All done! Return the interaction response so the user can check what happened
52+
// (hovered, clicked, ...) and maybe show a tooltip:
3753
response
3854
}
3955

@@ -45,5 +61,5 @@ fn toggle_switch_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
4561
/// ui.add(toggle_switch(&mut my_bool));
4662
/// ```
4763
pub fn toggle_switch(on: &mut bool) -> impl egui::Widget + '_ {
48-
move |ui: &mut egui::Ui| toggle_switch_ui(ui, on)
64+
move |ui: &mut egui::Ui| toggle_ui(ui, on)
4965
}

crates/re_viewer/src/app.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -326,20 +326,10 @@ impl App {
326326
Command::ToggleBlueprintPanel => {
327327
let blueprint = self.blueprint_mut(egui_ctx);
328328
blueprint.blueprint_panel_expanded ^= true;
329-
330-
// Only one of blueprint or selection panel can be open at a time on mobile:
331-
if is_narrow_screen && blueprint.blueprint_panel_expanded {
332-
blueprint.selection_panel_expanded = false;
333-
}
334329
}
335330
Command::ToggleSelectionPanel => {
336331
let blueprint = self.blueprint_mut(egui_ctx);
337332
blueprint.selection_panel_expanded ^= true;
338-
339-
// Only one of blueprint or selection panel can be open at a time on mobile:
340-
if is_narrow_screen && blueprint.selection_panel_expanded {
341-
blueprint.blueprint_panel_expanded = false;
342-
}
343333
}
344334
Command::ToggleTimePanel => {
345335
self.blueprint_mut(egui_ctx).time_panel_expanded ^= true;
@@ -1028,8 +1018,11 @@ struct AppState {
10281018
panel_selection: PanelSelection,
10291019

10301020
selection_panel: crate::selection_panel::SelectionPanel,
1021+
10311022
time_panel: crate::time_panel::TimePanel,
10321023

1024+
bottom_panel: crate::bottom_panel::BottomPanel,
1025+
10331026
selected_device: depthai::DeviceId,
10341027
depthai_state: depthai::State,
10351028

@@ -1060,6 +1053,7 @@ impl AppState {
10601053
blueprints,
10611054
selection_panel,
10621055
time_panel,
1056+
bottom_panel,
10631057
selected_device,
10641058
depthai_state,
10651059
#[cfg(not(target_arch = "wasm32"))]
@@ -1090,6 +1084,7 @@ impl AppState {
10901084
.or_insert_with(|| Blueprint::new(ui.ctx()));
10911085
// Hide time panel for now, reuse for recordings in the future
10921086
// time_panel.show_panel(&mut ctx, blueprint, ui);
1087+
// bottom_panel.show_panel(&mut ctx, blueprint, ui);
10931088
selection_panel.show_panel(&mut ctx, ui, blueprint);
10941089

10951090
let central_panel_frame = egui::Frame {

0 commit comments

Comments
 (0)