rat-focus 2.1.1

focus handling for ratatui widgets
Documentation
# Documentation details.


## Event handling


Event handling is implemented for crossterm. Focus implements
[HandleEvent][refHandleEvent], and there is also the function
[handle_focus](handle_focus) to invoke it.

It uses Tab/BackTab for navigation and handles mouse clicks on the widget's area.

```rust ignore
    // Handle events for focus.
let f = create_focus(state).handle(event, Regular);
```

It returns `Outcome::Changed` whenever something interesting has happened.
An `Outcome::Changed` should do a repaint, most widgets show their focus-state
somehow.

### Changed focus


When the focused widget changes, the newly focused widget has its
focus_gained flag set, and the previous widget its focus_lost flag.

A widget can also set callbacks for focus_gained and focus_lost
if it needs to react to changes.

## Mouse focus


Besides the (input) focus, there is also a mouse-focus flag.

This flag is set, if the event is a mouse-event, and any of
the widget-areas is hit by the mouse-event. This takes account
for widgets with overlapping areas, it also uses the z-index
of the widget-areas which widget should be concerned with
the mouse-event.

### Widget event handling


The widget can use its FocusFlag to decide the kind of event-handling
it should do. There is usually a big difference between focused and
not focused behavior.

If you are using some third party widget you can add a FocusFlag
somewhere to your state and use that to control the third party
widget. Or you may want to write a wrapper.

# Trait HasFocus


[HasFocus] is the main interface for widgets.

## Widgets


Simple widgets implement at least the first three functions of `HasFocus`.

- build() - For simple widgets with no internal structure this
  adds a leaf to the widget list.
  ```rust ignore
  fn build(&self, builder: &mut FocusBuilder) {
      builder.leaf_widget(self);
  }
  ```

- focus() - Return a clone of FocusFlag. There is a Rc inside, so this is a cheap clone.
- area() - Rendered area. This is used for mouse interaction.
  A widget can register multiple areas (e.g. ComboBox) too.
- area_z() - If a widget has an area that is logically `above` other widgets,
  it can use a z-value to indicate this. When testing for mouse interactions,
  areas with a higher z-value take priority.
  If areas with the same z-value overlap, the last one wins.
- navigable() - A control flag indicating __how__ the widget interacts
  with focus.

## Container widgets


When a widget contains other widgets it also implements HasFocus.

The primary function here is

- build() - This is called with the FocusBuilder and
  can add the separate component widgets of the container.

  You can have a FocusFlag marking the whole container.
  Such a FocusFlag sums the status of each component widget.
  That means the FocusFlag of the container 'is_focused' when any
  of the components 'is_focused'.

  If you manually call Focus::focus() for a container, the first
  component widget will get the focus. Similarly, if you click anywhere
  in the provided area the first component widget will get the focus.

```rust ignore
impl HasFocus for FooWidget {
    fn build(&self, builder: &mut FocusBuilder) {
        let tag = builder.start(self);
        builder.widget(&self.component_a);
        builder.widget(&self.component_b);
        builder.end(tag);
    }
}
```

This will use focus(), area() and area_z() to define the container.

If you don't need this, just leave it out

```rust ignore
impl HasFocus for FooWidget {
    fn build(&self, builder: &mut FocusBuilder) {
        builder.widget(&self.component_a);
        builder.widget(&self.component_b);
    }

    fn focus(&self) -> FocusFlag {
        unimplemented!("not in use");
    }

    fn area(&self) -> Rect {
        unimplemented!("not in use");
    }
}
```

This will just add more widgets to the focus. The focus() and area() functions
are still technically necessary, but are not used.

## Z-index for containers


If a container-widget sets a z-index, all the widgets added to the
container will use this z-index as a base. This ensures that mouse-interactions
with a complex popup work out.

## Mouse focus for containers.


The container mouse-focus will be set if the container itself registers
an area for mouse interactions. This differs from the input-focus, where
the container-flag is set if any of the widgets is focused.

If you stack containers, the mouse-focus will be set for all containers
that pass the hit-test. But; if you use a z-index for a container, none
of the containers with a lower z-index will have the flag set.

[refHandleEvent]: https://docs.rs/rat-event/latest/rat_event/trait.HandleEvent.html