@@ -240,49 +240,62 @@ impl<'a> EventCtx<'a> {
240
240
241
241
/// The focus status of a widget.
242
242
///
243
+ /// Returns `true` if this specific widget is focused.
244
+ /// To check if any descendants are focused use [`has_focus`].
245
+ ///
243
246
/// Focus means that the widget receives keyboard events.
244
247
///
245
248
/// A widget can request focus using the [`request_focus`] method.
246
- /// This will generally result in a separate event propagation of
247
- /// a `FocusChanged` method, including sending `false` to the previous
248
- /// widget that held focus.
249
+ /// It's also possible to register for automatic focus via [`register_for_focus`].
249
250
///
250
- /// Only one leaf widget at a time has focus. However, in a container
251
- /// hierarchy, all ancestors of that leaf widget are also invoked with
252
- /// `FocusChanged(true)`.
251
+ /// If a widget gains or loses focus it will get a [`LifeCycle::FocusChanged`] event.
253
252
///
254
- /// Discussion question: is "is_focused" a better name?
253
+ /// Only one widget at a time is focused. However due to the way events are routed,
254
+ /// all ancestors of that widget will also receive keyboard events.
255
255
///
256
256
/// [`request_focus`]: struct.EventCtx.html#method.request_focus
257
+ /// [`register_for_focus`]: struct.LifeCycleCtx.html#method.register_for_focus
258
+ /// [`LifeCycle::FocusChanged`]: enum.LifeCycle.html#variant.FocusChanged
259
+ /// [`has_focus`]: struct.EventCtx.html#method.has_focus
260
+ pub fn is_focused ( & self ) -> bool {
261
+ self . focus_widget == Some ( self . widget_id ( ) )
262
+ }
263
+
264
+ /// The (tree) focus status of a widget.
265
+ ///
266
+ /// Returns `true` if either this specific widget or any one of its descendants is focused.
267
+ /// To check if only this specific widget is focused use [`is_focused`].
268
+ ///
269
+ /// See [`is_focused`] for more information about focus.
270
+ ///
271
+ /// [`is_focused`]: struct.EventCtx.html#method.is_focused
257
272
pub fn has_focus ( & self ) -> bool {
273
+ // The bloom filter we're checking can return false positives.
258
274
let is_child = self
259
275
. focus_widget
260
- . map ( |id| self . base_state . children . contains ( & id) )
276
+ . map ( |id| self . base_state . children . may_contain ( & id) )
261
277
. unwrap_or ( false ) ;
262
278
is_child || self . focus_widget == Some ( self . widget_id ( ) )
263
279
}
264
280
265
- /// The (leaf) focus status of a widget. See [`has_focus`].
266
- ///
267
- /// [`has_focus`]: struct.EventCtx.html#method.has_focus
268
- pub fn is_focused ( & self ) -> bool {
269
- self . focus_widget == Some ( self . widget_id ( ) )
270
- }
271
-
272
281
/// Request keyboard focus.
273
282
///
274
- /// See [`has_focus `] for more information.
283
+ /// See [`is_focused `] for more information about focus .
275
284
///
276
- /// [`has_focus `]: struct.EventCtx.html#method.has_focus
285
+ /// [`is_focused `]: struct.EventCtx.html#method.is_focused
277
286
pub fn request_focus ( & mut self ) {
278
287
self . base_state . request_focus = Some ( FocusChange :: Focus ( self . widget_id ( ) ) ) ;
279
288
}
280
289
281
290
/// Transfer focus to the next focusable widget.
282
291
///
283
292
/// This should only be called by a widget that currently has focus.
293
+ ///
294
+ /// See [`is_focused`] for more information about focus.
295
+ ///
296
+ /// [`is_focused`]: struct.EventCtx.html#method.is_focused
284
297
pub fn focus_next ( & mut self ) {
285
- if self . focus_widget == Some ( self . widget_id ( ) ) {
298
+ if self . is_focused ( ) {
286
299
self . base_state . request_focus = Some ( FocusChange :: Next ) ;
287
300
} else {
288
301
log:: warn!( "focus_next can only be called by the currently focused widget" ) ;
@@ -292,8 +305,12 @@ impl<'a> EventCtx<'a> {
292
305
/// Transfer focus to the previous focusable widget.
293
306
///
294
307
/// This should only be called by a widget that currently has focus.
308
+ ///
309
+ /// See [`is_focused`] for more information about focus.
310
+ ///
311
+ /// [`is_focused`]: struct.EventCtx.html#method.is_focused
295
312
pub fn focus_prev ( & mut self ) {
296
- if self . focus_widget == Some ( self . widget_id ( ) ) {
313
+ if self . is_focused ( ) {
297
314
self . base_state . request_focus = Some ( FocusChange :: Previous ) ;
298
315
} else {
299
316
log:: warn!( "focus_prev can only be called by the currently focused widget" ) ;
@@ -303,8 +320,12 @@ impl<'a> EventCtx<'a> {
303
320
/// Give up focus.
304
321
///
305
322
/// This should only be called by a widget that currently has focus.
323
+ ///
324
+ /// See [`is_focused`] for more information about focus.
325
+ ///
326
+ /// [`is_focused`]: struct.EventCtx.html#method.is_focused
306
327
pub fn resign_focus ( & mut self ) {
307
- if self . focus_widget == Some ( self . widget_id ( ) ) {
328
+ if self . is_focused ( ) {
308
329
self . base_state . request_focus = Some ( FocusChange :: Resign ) ;
309
330
} else {
310
331
log:: warn!( "resign_focus can only be called by the currently focused widget" ) ;
@@ -414,6 +435,13 @@ impl<'a> LifeCycleCtx<'a> {
414
435
}
415
436
416
437
/// Register this widget to be eligile to accept focus automatically.
438
+ ///
439
+ /// This should only be called in response to a [`LifeCycle::WidgetAdded`] event.
440
+ ///
441
+ /// See [`EventCtx::is_focused`] for more information about focus.
442
+ ///
443
+ /// [`LifeCycle::WidgetAdded`]: enum.Lifecycle.html#variant.WidgetAdded
444
+ /// [`EventCtx::is_focused`]: struct.EventCtx.html#method.is_focused
417
445
pub fn register_for_focus ( & mut self ) {
418
446
self . base_state . focus_chain . push ( self . widget_id ( ) ) ;
419
447
}
@@ -557,20 +585,33 @@ impl<'a, 'b: 'a> PaintCtx<'a, 'b> {
557
585
self . base_state . size ( )
558
586
}
559
587
560
- /// Query the focus state of the widget.
588
+ /// The focus status of a widget.
589
+ ///
590
+ /// Returns `true` if this specific widget is focused.
591
+ /// To check if any descendants are focused use [`has_focus`].
592
+ ///
593
+ /// See [`EventCtx::is_focused`] for more information about focus.
561
594
///
562
- /// This is true only if this widget has focus.
595
+ /// [`has_focus`]: #method.has_focus
596
+ /// [`EventCtx::is_focused`]: struct.EventCtx.html#method.is_focused
563
597
pub fn is_focused ( & self ) -> bool {
564
598
self . focus_widget == Some ( self . widget_id ( ) )
565
599
}
566
600
567
- /// The focus status of a widget.
601
+ /// The (tree) focus status of a widget.
602
+ ///
603
+ /// Returns `true` if either this specific widget or any one of its descendants is focused.
604
+ /// To check if only this specific widget is focused use [`is_focused`].
605
+ ///
606
+ /// See [`EventCtx::is_focused`] for more information about focus.
568
607
///
569
- /// See [`has_focus`](struct.EventCtx.html#method.has_focus).
608
+ /// [`is_focused`]: #method.is_focused
609
+ /// [`EventCtx::is_focused`]: struct.EventCtx.html#method.is_focused
570
610
pub fn has_focus ( & self ) -> bool {
611
+ // The bloom filter we're checking can return false positives.
571
612
let is_child = self
572
613
. focus_widget
573
- . map ( |id| self . base_state . children . contains ( & id) )
614
+ . map ( |id| self . base_state . children . may_contain ( & id) )
574
615
. unwrap_or ( false ) ;
575
616
is_child || self . focus_widget == Some ( self . widget_id ( ) )
576
617
}
0 commit comments