text_selection_toolbar_button.dart 4.52 KB
Newer Older
1 2 3 4 5 6 7 8
// 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.

import 'package:flutter/widgets.dart';

import 'button.dart';
import 'colors.dart';
9 10
import 'debug.dart';
import 'localizations.dart';
11 12 13 14 15 16 17 18 19 20

const TextStyle _kToolbarButtonFontStyle = TextStyle(
  inherit: false,
  fontSize: 14.0,
  letterSpacing: -0.15,
  fontWeight: FontWeight.w400,
);

// Colors extracted from https://developer.apple.com/design/resources/.
// TODO(LongCatIsLooong): https://github.com/flutter/flutter/issues/41507.
21 22 23 24 25 26 27 28 29 30 31
const CupertinoDynamicColor _kToolbarBackgroundColor = CupertinoDynamicColor.withBrightness(
  // This value was extracted from a screenshot of iOS 16.0.3, as light mode
  // didn't appear in the Apple design resources assets linked above.
  color: Color(0xEBF7F7F7),
  darkColor: Color(0xEB202020),
);

const CupertinoDynamicColor _kToolbarTextColor = CupertinoDynamicColor.withBrightness(
  color: CupertinoColors.black,
  darkColor: CupertinoColors.white,
);
32 33 34 35 36 37 38

// Eyeballed value.
const EdgeInsets _kToolbarButtonPadding = EdgeInsets.symmetric(vertical: 16.0, horizontal: 18.0);

/// A button in the style of the iOS text selection toolbar buttons.
class CupertinoTextSelectionToolbarButton extends StatelessWidget {
  /// Create an instance of [CupertinoTextSelectionToolbarButton].
39 40
  ///
  /// [child] cannot be null.
41
  const CupertinoTextSelectionToolbarButton({
42
    super.key,
43
    this.onPressed,
44
    required Widget this.child,
45
  }) : text = null,
46
       buttonItem = null;
47 48 49

  /// Create an instance of [CupertinoTextSelectionToolbarButton] whose child is
  /// a [Text] widget styled like the default iOS text selection toolbar button.
50
  const CupertinoTextSelectionToolbarButton.text({
51
    super.key,
52
    this.onPressed,
53
    required this.text,
54
  }) : buttonItem = null,
55
       child = null;
56

57 58 59 60 61 62 63
  /// Create an instance of [CupertinoTextSelectionToolbarButton] from the given
  /// [ContextMenuButtonItem].
  ///
  /// [buttonItem] cannot be null.
  CupertinoTextSelectionToolbarButton.buttonItem({
    super.key,
    required ContextMenuButtonItem this.buttonItem,
64
  }) : child = null,
65
       text = null,
66 67
       onPressed = buttonItem.onPressed;

68
  /// {@template flutter.cupertino.CupertinoTextSelectionToolbarButton.child}
69 70 71
  /// The child of this button.
  ///
  /// Usually a [Text] or an [Icon].
72
  /// {@endtemplate}
73
  final Widget? child;
74

75
  /// {@template flutter.cupertino.CupertinoTextSelectionToolbarButton.onPressed}
76
  /// Called when this button is pressed.
77
  /// {@endtemplate}
78 79
  final VoidCallback? onPressed;

80 81 82 83 84 85
  /// {@template flutter.cupertino.CupertinoTextSelectionToolbarButton.onPressed}
  /// The buttonItem used to generate the button when using
  /// [CupertinoTextSelectionToolbarButton.buttonItem].
  /// {@endtemplate}
  final ContextMenuButtonItem? buttonItem;

86 87 88 89
  /// The text used in the button's label when using
  /// [CupertinoTextSelectionToolbarButton.text].
  final String? text;

90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
  /// Returns the default button label String for the button of the given
  /// [ContextMenuButtonItem]'s [ContextMenuButtonType].
  static String getButtonLabel(BuildContext context, ContextMenuButtonItem buttonItem) {
    if (buttonItem.label != null) {
      return buttonItem.label!;
    }

    assert(debugCheckHasCupertinoLocalizations(context));
    final CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
    switch (buttonItem.type) {
      case ContextMenuButtonType.cut:
        return localizations.cutButtonLabel;
      case ContextMenuButtonType.copy:
        return localizations.copyButtonLabel;
      case ContextMenuButtonType.paste:
        return localizations.pasteButtonLabel;
      case ContextMenuButtonType.selectAll:
        return localizations.selectAllButtonLabel;
108
      case ContextMenuButtonType.delete:
109 110 111 112 113
      case ContextMenuButtonType.custom:
        return '';
    }
  }

114 115
  @override
  Widget build(BuildContext context) {
116
    final Widget child = this.child ?? Text(
117 118 119 120 121 122 123 124 125
       text ?? getButtonLabel(context, buttonItem!),
       overflow: TextOverflow.ellipsis,
       style: _kToolbarButtonFontStyle.copyWith(
         color: onPressed != null
             ? _kToolbarTextColor.resolveFrom(context)
             : CupertinoColors.inactiveGray,
       ),
     );

126 127 128 129 130 131 132 133 134 135 136
    return CupertinoButton(
      borderRadius: null,
      color: _kToolbarBackgroundColor,
      disabledColor: _kToolbarBackgroundColor,
      onPressed: onPressed,
      padding: _kToolbarButtonPadding,
      pressedOpacity: onPressed == null ? 1.0 : 0.7,
      child: child,
    );
  }
}