// 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 'material.dart'; import 'text_selection_toolbar.dart'; // These values were measured from a screenshot of TextEdit on macOS 10.15.7 on // a Macbook Pro. const double _kToolbarScreenPadding = 8.0; const double _kToolbarWidth = 222.0; /// A Material-style desktop text selection toolbar. /// /// Typically displays buttons for text manipulation, e.g. copying and pasting /// text. /// /// Tries to position its top left corner as closely as possible to [anchor] /// while remaining fully inside the viewport. /// /// See also: /// /// * [AdaptiveTextSelectionToolbar], which builds the toolbar for the current /// platform. /// * [TextSelectionToolbar], which is similar, but builds an Android-style /// toolbar. class DesktopTextSelectionToolbar extends StatelessWidget { /// Creates a const instance of DesktopTextSelectionToolbar. const DesktopTextSelectionToolbar({ super.key, required this.anchor, required this.children, }) : assert(children.length > 0); /// {@template flutter.material.DesktopTextSelectionToolbar.anchor} /// The point where the toolbar will attempt to position itself as closely as /// possible. /// {@endtemplate} final Offset anchor; /// {@macro flutter.material.TextSelectionToolbar.children} /// /// See also: /// * [DesktopTextSelectionToolbarButton], which builds a default /// Material-style desktop text selection toolbar text button. final List<Widget> children; // Builds a desktop toolbar in the Material style. static Widget _defaultToolbarBuilder(BuildContext context, Widget child) { return SizedBox( width: _kToolbarWidth, child: Material( borderRadius: const BorderRadius.all(Radius.circular(7.0)), clipBehavior: Clip.antiAlias, elevation: 1.0, type: MaterialType.card, child: child, ), ); } @override Widget build(BuildContext context) { assert(debugCheckHasMediaQuery(context)); final double paddingAbove = MediaQuery.paddingOf(context).top + _kToolbarScreenPadding; final Offset localAdjustment = Offset(_kToolbarScreenPadding, paddingAbove); return Padding( padding: EdgeInsets.fromLTRB( _kToolbarScreenPadding, paddingAbove, _kToolbarScreenPadding, _kToolbarScreenPadding, ), child: CustomSingleChildLayout( delegate: DesktopTextSelectionToolbarLayoutDelegate( anchor: anchor - localAdjustment, ), child: _defaultToolbarBuilder( context, Column( mainAxisSize: MainAxisSize.min, children: children, ), ), ), ); } }