onKey method

  1. @override
bool onKey(
  1. KeyEvent event,
  2. RenderContext ctx
)
override

Implementation

@override
bool onKey(KeyEvent event, RenderContext ctx) {
  final visible = _flatten();
  if (visible.isEmpty) return false;
  state.activeIndex = state.activeIndex.clamp(0, visible.length - 1);
  final active = visible[state.activeIndex];

  switch (event.key) {
    case NamedKey.arrowUp:
      if (state.activeIndex > 0) state.activeIndex -= 1;
      return true;
    case NamedKey.arrowDown:
      if (state.activeIndex < visible.length - 1) state.activeIndex += 1;
      return true;
    case NamedKey.arrowLeft:
      if (!active.node.isLeaf && state.expanded.contains(active.key)) {
        state.expanded.remove(active.key);
        onExpansionChanged?.call(active.node, false);
        return true;
      }
      // Otherwise jump to parent: find previous item with depth - 1.
      for (var i = state.activeIndex - 1; i >= 0; i--) {
        if (visible[i].depth < active.depth) {
          state.activeIndex = i;
          break;
        }
      }
      return true;
    case NamedKey.arrowRight:
      if (active.node.isLeaf) return true;
      if (!state.expanded.contains(active.key)) {
        state.expanded.add(active.key);
        onExpansionChanged?.call(active.node, true);
      } else if (state.activeIndex < visible.length - 1) {
        state.activeIndex += 1;
      }
      return true;
    case NamedKey.home:
      state.activeIndex = 0;
      return true;
    case NamedKey.end:
      state.activeIndex = visible.length - 1;
      return true;
    case NamedKey.enter:
      if (active.node.isLeaf) {
        onActivate?.call(active.node);
      } else {
        _toggle(active);
      }
      return true;
    default:
      if (event.char == ' ') {
        _toggle(active);
        return true;
      }
      return false;
  }
}