1
1
use egui:: NumExt as _;
2
+ use itertools:: Itertools ;
2
3
use re_format:: format_number;
3
4
use re_renderer:: WgpuResourcePoolStatistics ;
5
+ use re_smart_channel:: { ReceiveSet , SmartChannelSource } ;
4
6
use re_ui:: UICommand ;
5
7
use re_viewer_context:: StoreContext ;
6
8
7
9
use crate :: { app_blueprint:: AppBlueprint , App } ;
8
10
9
11
pub fn top_panel (
12
+ app : & mut App ,
10
13
app_blueprint : & AppBlueprint < ' _ > ,
11
14
store_context : Option < & StoreContext < ' _ > > ,
12
- ui : & mut egui:: Ui ,
13
- app : & mut App ,
14
15
gpu_resource_stats : & WgpuResourcePoolStatistics ,
16
+ ui : & mut egui:: Ui ,
15
17
) {
16
18
re_tracing:: profile_function!( ) ;
17
19
@@ -26,10 +28,11 @@ pub fn top_panel(
26
28
ui. set_height ( top_bar_style. height ) ;
27
29
ui. add_space ( top_bar_style. indent ) ;
28
30
29
- top_bar_ui ( app_blueprint, store_context, ui, app , gpu_resource_stats) ;
31
+ top_bar_ui ( app , app_blueprint, store_context, ui, gpu_resource_stats) ;
30
32
} )
31
33
. response ;
32
34
35
+ // React to dragging and double-clicking the top bar:
33
36
#[ cfg( not( target_arch = "wasm32" ) ) ]
34
37
if !re_ui:: NATIVE_WINDOW_BAR {
35
38
let title_bar_response = _response. interact ( egui:: Sense :: click ( ) ) ;
@@ -45,10 +48,10 @@ pub fn top_panel(
45
48
}
46
49
47
50
fn top_bar_ui (
51
+ app : & mut App ,
48
52
app_blueprint : & AppBlueprint < ' _ > ,
49
53
store_context : Option < & StoreContext < ' _ > > ,
50
54
ui : & mut egui:: Ui ,
51
- app : & mut App ,
52
55
gpu_resource_stats : & WgpuResourcePoolStatistics ,
53
56
) {
54
57
app. rerun_menu_button_ui ( store_context, ui) ;
@@ -76,58 +79,11 @@ fn top_bar_ui(
76
79
ui. add_space ( extra_margin) ;
77
80
}
78
81
79
- let mut selection_panel_expanded = app_blueprint. selection_panel_expanded ;
80
- if app
81
- . re_ui ( )
82
- . medium_icon_toggle_button (
83
- ui,
84
- & re_ui:: icons:: RIGHT_PANEL_TOGGLE ,
85
- & mut selection_panel_expanded,
86
- )
87
- . on_hover_text ( format ! (
88
- "Toggle Selection View{}" ,
89
- UICommand :: ToggleSelectionPanel . format_shortcut_tooltip_suffix( ui. ctx( ) )
90
- ) )
91
- . clicked ( )
92
- {
93
- app_blueprint. toggle_selection_panel ( & app. command_sender ) ;
94
- }
95
-
96
- let mut time_panel_expanded = app_blueprint. time_panel_expanded ;
97
- if app
98
- . re_ui ( )
99
- . medium_icon_toggle_button (
100
- ui,
101
- & re_ui:: icons:: BOTTOM_PANEL_TOGGLE ,
102
- & mut time_panel_expanded,
103
- )
104
- . on_hover_text ( format ! (
105
- "Toggle Timeline View{}" ,
106
- UICommand :: ToggleTimePanel . format_shortcut_tooltip_suffix( ui. ctx( ) )
107
- ) )
108
- . clicked ( )
109
- {
110
- app_blueprint. toggle_time_panel ( & app. command_sender ) ;
111
- }
82
+ panel_buttons_r2l ( app, app_blueprint, ui) ;
112
83
113
- let mut blueprint_panel_expanded = app_blueprint. blueprint_panel_expanded ;
114
- if app
115
- . re_ui ( )
116
- . medium_icon_toggle_button (
117
- ui,
118
- & re_ui:: icons:: LEFT_PANEL_TOGGLE ,
119
- & mut blueprint_panel_expanded,
120
- )
121
- . on_hover_text ( format ! (
122
- "Toggle Blueprint View{}" ,
123
- UICommand :: ToggleBlueprintPanel . format_shortcut_tooltip_suffix( ui. ctx( ) )
124
- ) )
125
- . clicked ( )
126
- {
127
- app_blueprint. toggle_blueprint_panel ( & app. command_sender ) ;
128
- }
84
+ connection_status_ui ( ui, app. msg_receive_set ( ) ) ;
129
85
130
- if cfg ! ( debug_assertions) && app . app_options ( ) . show_metrics {
86
+ if cfg ! ( debug_assertions) {
131
87
ui. vertical_centered ( |ui| {
132
88
ui. style_mut ( ) . wrap = Some ( false ) ;
133
89
ui. add_space ( 6.0 ) ; // TODO(emilk): in egui, add a proper way of centering a single widget in a UI.
@@ -137,6 +93,143 @@ fn top_bar_ui(
137
93
} ) ;
138
94
}
139
95
96
+ fn connection_status_ui ( ui : & mut egui:: Ui , rx : & ReceiveSet < re_log_types:: LogMsg > ) {
97
+ let sources = rx
98
+ . sources ( )
99
+ . into_iter ( )
100
+ . filter ( |source| {
101
+ match source. as_ref ( ) {
102
+ SmartChannelSource :: File ( _) | SmartChannelSource :: RrdHttpStream { .. } => {
103
+ false // These show up in the recordings panel as a "Loading…" in `recordings_panel.rs`
104
+ }
105
+
106
+ re_smart_channel:: SmartChannelSource :: RrdWebEventListener
107
+ | re_smart_channel:: SmartChannelSource :: Sdk
108
+ | re_smart_channel:: SmartChannelSource :: WsClient { .. }
109
+ | re_smart_channel:: SmartChannelSource :: TcpServer { .. } => true ,
110
+ }
111
+ } )
112
+ . collect_vec ( ) ;
113
+
114
+ match sources. len ( ) {
115
+ 0 => return ,
116
+ 1 => {
117
+ source_label ( ui, sources[ 0 ] . as_ref ( ) ) ;
118
+ }
119
+ n => {
120
+ // In practice we never get here
121
+ ui. label ( format ! ( "{n} sources connected" ) )
122
+ . on_hover_ui ( |ui| {
123
+ ui. vertical ( |ui| {
124
+ for source in & sources {
125
+ source_label ( ui, source. as_ref ( ) ) ;
126
+ }
127
+ } ) ;
128
+ } ) ;
129
+ }
130
+ }
131
+
132
+ fn source_label ( ui : & mut egui:: Ui , source : & SmartChannelSource ) -> egui:: Response {
133
+ let response = ui. label ( status_string ( source) ) ;
134
+
135
+ let tooltip = match source {
136
+ SmartChannelSource :: File ( _)
137
+ | SmartChannelSource :: RrdHttpStream { .. }
138
+ | SmartChannelSource :: RrdWebEventListener
139
+ | SmartChannelSource :: Sdk
140
+ | SmartChannelSource :: WsClient { .. } => None ,
141
+
142
+ SmartChannelSource :: TcpServer { .. } => {
143
+ Some ( "Waiting for an SDK to connect" . to_owned ( ) )
144
+ }
145
+ } ;
146
+
147
+ if let Some ( tooltip) = tooltip {
148
+ response. on_hover_text ( tooltip)
149
+ } else {
150
+ response
151
+ }
152
+ }
153
+
154
+ fn status_string ( source : & SmartChannelSource ) -> String {
155
+ match source {
156
+ re_smart_channel:: SmartChannelSource :: File ( path) => {
157
+ format ! ( "Loading {}…" , path. display( ) )
158
+ }
159
+ re_smart_channel:: SmartChannelSource :: RrdHttpStream { url } => {
160
+ format ! ( "Loading {url}…" )
161
+ }
162
+ re_smart_channel:: SmartChannelSource :: RrdWebEventListener => {
163
+ "Waiting for logging data…" . to_owned ( )
164
+ }
165
+ re_smart_channel:: SmartChannelSource :: Sdk => {
166
+ "Waiting for logging data from SDK" . to_owned ( )
167
+ }
168
+ re_smart_channel:: SmartChannelSource :: WsClient { ws_server_url } => {
169
+ // TODO(emilk): it would be even better to know whether or not we are connected, or are attempting to connect
170
+ format ! ( "Waiting for data from {ws_server_url}" )
171
+ }
172
+ re_smart_channel:: SmartChannelSource :: TcpServer { port } => {
173
+ format ! ( "Listening on TCP port {port}" )
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ /// Lay out the panel button right-to-left
180
+ fn panel_buttons_r2l ( app : & App , app_blueprint : & AppBlueprint < ' _ > , ui : & mut egui:: Ui ) {
181
+ let mut selection_panel_expanded = app_blueprint. selection_panel_expanded ;
182
+ if app
183
+ . re_ui ( )
184
+ . medium_icon_toggle_button (
185
+ ui,
186
+ & re_ui:: icons:: RIGHT_PANEL_TOGGLE ,
187
+ & mut selection_panel_expanded,
188
+ )
189
+ . on_hover_text ( format ! (
190
+ "Toggle Selection View{}" ,
191
+ UICommand :: ToggleSelectionPanel . format_shortcut_tooltip_suffix( ui. ctx( ) )
192
+ ) )
193
+ . clicked ( )
194
+ {
195
+ app_blueprint. toggle_selection_panel ( & app. command_sender ) ;
196
+ }
197
+
198
+ let mut time_panel_expanded = app_blueprint. time_panel_expanded ;
199
+ if app
200
+ . re_ui ( )
201
+ . medium_icon_toggle_button (
202
+ ui,
203
+ & re_ui:: icons:: BOTTOM_PANEL_TOGGLE ,
204
+ & mut time_panel_expanded,
205
+ )
206
+ . on_hover_text ( format ! (
207
+ "Toggle Timeline View{}" ,
208
+ UICommand :: ToggleTimePanel . format_shortcut_tooltip_suffix( ui. ctx( ) )
209
+ ) )
210
+ . clicked ( )
211
+ {
212
+ app_blueprint. toggle_time_panel ( & app. command_sender ) ;
213
+ }
214
+
215
+ let mut blueprint_panel_expanded = app_blueprint. blueprint_panel_expanded ;
216
+ if app
217
+ . re_ui ( )
218
+ . medium_icon_toggle_button (
219
+ ui,
220
+ & re_ui:: icons:: LEFT_PANEL_TOGGLE ,
221
+ & mut blueprint_panel_expanded,
222
+ )
223
+ . on_hover_text ( format ! (
224
+ "Toggle Blueprint View{}" ,
225
+ UICommand :: ToggleBlueprintPanel . format_shortcut_tooltip_suffix( ui. ctx( ) )
226
+ ) )
227
+ . clicked ( )
228
+ {
229
+ app_blueprint. toggle_blueprint_panel ( & app. command_sender ) ;
230
+ }
231
+ }
232
+
140
233
/// Shows clickable website link as an image (text doesn't look as nice)
141
234
fn website_link_ui ( ui : & mut egui:: Ui ) {
142
235
let desired_height = ui. max_rect ( ) . height ( ) ;
0 commit comments