@@ -6,6 +6,29 @@ use crate::*;
6
6
7
7
// ----------------------------------------------------------------------------
8
8
9
+ fn when_was_a_toolip_last_shown_id ( ) -> Id {
10
+ Id :: new ( "when_was_a_toolip_last_shown" )
11
+ }
12
+
13
+ pub fn seconds_since_last_tooltip ( ctx : & Context ) -> f32 {
14
+ let when_was_a_toolip_last_shown =
15
+ ctx. data ( |d| d. get_temp :: < f64 > ( when_was_a_toolip_last_shown_id ( ) ) ) ;
16
+
17
+ if let Some ( when_was_a_toolip_last_shown) = when_was_a_toolip_last_shown {
18
+ let now = ctx. input ( |i| i. time ) ;
19
+ ( now - when_was_a_toolip_last_shown) as f32
20
+ } else {
21
+ f32:: INFINITY
22
+ }
23
+ }
24
+
25
+ fn remember_that_tooltip_was_shown ( ctx : & Context ) {
26
+ let now = ctx. input ( |i| i. time ) ;
27
+ ctx. data_mut ( |data| data. insert_temp :: < f64 > ( when_was_a_toolip_last_shown_id ( ) , now) ) ;
28
+ }
29
+
30
+ // ----------------------------------------------------------------------------
31
+
9
32
/// Show a tooltip at the current pointer position (if any).
10
33
///
11
34
/// Most of the time it is easier to use [`Response::on_hover_ui`].
@@ -123,14 +146,16 @@ fn show_tooltip_at_dyn<'c, R>(
123
146
widget_rect = transform * widget_rect;
124
147
}
125
148
126
- // if there are multiple tooltips open they should use the same common_id for the `tooltip_size` caching to work.
149
+ remember_that_tooltip_was_shown ( ctx) ;
150
+
127
151
let mut state = ctx. frame_state_mut ( |fs| {
128
152
// Remember that this is the widget showing the tooltip:
129
- fs. tooltip_state
130
- . per_layer_tooltip_widget
131
- . insert ( parent_layer, widget_id) ;
153
+ fs. layers
154
+ . entry ( parent_layer)
155
+ . or_default ( )
156
+ . widget_with_tooltip = Some ( widget_id) ;
132
157
133
- fs. tooltip_state
158
+ fs. tooltips
134
159
. widget_tooltips
135
160
. get ( & widget_id)
136
161
. copied ( )
@@ -174,15 +199,15 @@ fn show_tooltip_at_dyn<'c, R>(
174
199
175
200
state. tooltip_count += 1 ;
176
201
state. bounding_rect = state. bounding_rect . union ( response. rect ) ;
177
- ctx. frame_state_mut ( |fs| fs. tooltip_state . widget_tooltips . insert ( widget_id, state) ) ;
202
+ ctx. frame_state_mut ( |fs| fs. tooltips . widget_tooltips . insert ( widget_id, state) ) ;
178
203
179
204
inner
180
205
}
181
206
182
207
/// What is the id of the next tooltip for this widget?
183
208
pub fn next_tooltip_id ( ctx : & Context , widget_id : Id ) -> Id {
184
209
let tooltip_count = ctx. frame_state ( |fs| {
185
- fs. tooltip_state
210
+ fs. tooltips
186
211
. widget_tooltips
187
212
. get ( & widget_id)
188
213
. map_or ( 0 , |state| state. tooltip_count )
@@ -351,53 +376,61 @@ pub fn popup_above_or_below_widget<R>(
351
376
close_behavior : PopupCloseBehavior ,
352
377
add_contents : impl FnOnce ( & mut Ui ) -> R ,
353
378
) -> Option < R > {
354
- if parent_ui. memory ( |mem| mem. is_popup_open ( popup_id) ) {
355
- let ( mut pos, pivot) = match above_or_below {
356
- AboveOrBelow :: Above => ( widget_response. rect . left_top ( ) , Align2 :: LEFT_BOTTOM ) ,
357
- AboveOrBelow :: Below => ( widget_response. rect . left_bottom ( ) , Align2 :: LEFT_TOP ) ,
358
- } ;
359
- if let Some ( transform) = parent_ui
360
- . ctx ( )
361
- . memory ( |m| m. layer_transforms . get ( & parent_ui. layer_id ( ) ) . copied ( ) )
362
- {
363
- pos = transform * pos;
364
- }
379
+ if !parent_ui. memory ( |mem| mem. is_popup_open ( popup_id) ) {
380
+ return None ;
381
+ }
382
+
383
+ let ( mut pos, pivot) = match above_or_below {
384
+ AboveOrBelow :: Above => ( widget_response. rect . left_top ( ) , Align2 :: LEFT_BOTTOM ) ,
385
+ AboveOrBelow :: Below => ( widget_response. rect . left_bottom ( ) , Align2 :: LEFT_TOP ) ,
386
+ } ;
387
+ if let Some ( transform) = parent_ui
388
+ . ctx ( )
389
+ . memory ( |m| m. layer_transforms . get ( & parent_ui. layer_id ( ) ) . copied ( ) )
390
+ {
391
+ pos = transform * pos;
392
+ }
393
+
394
+ let frame = Frame :: popup ( parent_ui. style ( ) ) ;
395
+ let frame_margin = frame. total_margin ( ) ;
396
+ let inner_width = widget_response. rect . width ( ) - frame_margin. sum ( ) . x ;
397
+
398
+ parent_ui. ctx ( ) . frame_state_mut ( |fs| {
399
+ fs. layers
400
+ . entry ( parent_ui. layer_id ( ) )
401
+ . or_default ( )
402
+ . open_popups
403
+ . insert ( popup_id)
404
+ } ) ;
365
405
366
- let frame = Frame :: popup ( parent_ui. style ( ) ) ;
367
- let frame_margin = frame. total_margin ( ) ;
368
- let inner_width = widget_response. rect . width ( ) - frame_margin. sum ( ) . x ;
369
-
370
- let response = Area :: new ( popup_id)
371
- . kind ( UiKind :: Popup )
372
- . order ( Order :: Foreground )
373
- . fixed_pos ( pos)
374
- . default_width ( inner_width)
375
- . pivot ( pivot)
376
- . show ( parent_ui. ctx ( ) , |ui| {
377
- frame
378
- . show ( ui, |ui| {
379
- ui. with_layout ( Layout :: top_down_justified ( Align :: LEFT ) , |ui| {
380
- ui. set_min_width ( inner_width) ;
381
- add_contents ( ui)
382
- } )
383
- . inner
406
+ let response = Area :: new ( popup_id)
407
+ . kind ( UiKind :: Popup )
408
+ . order ( Order :: Foreground )
409
+ . fixed_pos ( pos)
410
+ . default_width ( inner_width)
411
+ . pivot ( pivot)
412
+ . show ( parent_ui. ctx ( ) , |ui| {
413
+ frame
414
+ . show ( ui, |ui| {
415
+ ui. with_layout ( Layout :: top_down_justified ( Align :: LEFT ) , |ui| {
416
+ ui. set_min_width ( inner_width) ;
417
+ add_contents ( ui)
384
418
} )
385
419
. inner
386
- } ) ;
387
-
388
- let should_close = match close_behavior {
389
- PopupCloseBehavior :: CloseOnClick => widget_response. clicked_elsewhere ( ) ,
390
- PopupCloseBehavior :: CloseOnClickOutside => {
391
- widget_response. clicked_elsewhere ( ) && response. response . clicked_elsewhere ( )
392
- }
393
- PopupCloseBehavior :: IgnoreClicks => false ,
394
- } ;
395
-
396
- if parent_ui. input ( |i| i. key_pressed ( Key :: Escape ) ) || should_close {
397
- parent_ui. memory_mut ( |mem| mem. close_popup ( ) ) ;
420
+ } )
421
+ . inner
422
+ } ) ;
423
+
424
+ let should_close = match close_behavior {
425
+ PopupCloseBehavior :: CloseOnClick => widget_response. clicked_elsewhere ( ) ,
426
+ PopupCloseBehavior :: CloseOnClickOutside => {
427
+ widget_response. clicked_elsewhere ( ) && response. response . clicked_elsewhere ( )
398
428
}
399
- Some ( response. inner )
400
- } else {
401
- None
429
+ PopupCloseBehavior :: IgnoreClicks => false ,
430
+ } ;
431
+
432
+ if parent_ui. input ( |i| i. key_pressed ( Key :: Escape ) ) || should_close {
433
+ parent_ui. memory_mut ( |mem| mem. close_popup ( ) ) ;
402
434
}
435
+ Some ( response. inner )
403
436
}
0 commit comments