// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// Flutter code sample for [RadioMenuButton].

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MenuApp());

class MyRadioMenu extends StatefulWidget {
  const MyRadioMenu({super.key});

  @override
  State<MyRadioMenu> createState() => _MyRadioMenuState();
}

class _MyRadioMenuState extends State<MyRadioMenu> {
  final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Menu Button');
  Color _backgroundColor = Colors.red;
  late ShortcutRegistryEntry _entry;

  static const SingleActivator _redShortcut = SingleActivator(LogicalKeyboardKey.keyR, control: true);
  static const SingleActivator _greenShortcut = SingleActivator(LogicalKeyboardKey.keyG, control: true);
  static const SingleActivator _blueShortcut = SingleActivator(LogicalKeyboardKey.keyB, control: true);

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _entry = ShortcutRegistry.of(context).addAll(<ShortcutActivator, VoidCallbackIntent>{
        _redShortcut: VoidCallbackIntent(() => _setBackgroundColor(Colors.red)),
        _greenShortcut: VoidCallbackIntent(() => _setBackgroundColor(Colors.green)),
        _blueShortcut: VoidCallbackIntent(() => _setBackgroundColor(Colors.blue)),
      });
  }

  @override
  void dispose() {
    _buttonFocusNode.dispose();
    _entry.dispose();
    super.dispose();
  }

  void _setBackgroundColor(Color? color) {
    setState(() {
      _backgroundColor = color!;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        MenuAnchor(
          childFocusNode: _buttonFocusNode,
          menuChildren: <Widget>[
            RadioMenuButton<Color>(
              value: Colors.red,
              shortcut: _redShortcut,
              groupValue: _backgroundColor,
              onChanged: _setBackgroundColor,
              child: const Text('Red Background'),
            ),
            RadioMenuButton<Color>(
              value: Colors.green,
              shortcut: _greenShortcut,
              groupValue: _backgroundColor,
              onChanged: _setBackgroundColor,
              child: const Text('Green Background'),
            ),
            RadioMenuButton<Color>(
              value: Colors.blue,
              shortcut: _blueShortcut,
              groupValue: _backgroundColor,
              onChanged: _setBackgroundColor,
              child: const Text('Blue Background'),
            ),
          ],
          builder: (BuildContext context, MenuController controller, Widget? child) {
            return TextButton(
              focusNode: _buttonFocusNode,
              onPressed: () {
                if (controller.isOpen) {
                  controller.close();
                } else {
                  controller.open();
                }
              },
              child: const Text('OPEN MENU'),
            );
          },
        ),
        Expanded(
          child: Container(
            color: _backgroundColor,
          ),
        ),
      ],
    );
  }
}

class MenuApp extends StatelessWidget {
  const MenuApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(body: MyRadioMenu()),
    );
  }
}
