Hibok
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

240 lines
7.4 KiB

  1. import 'package:chat/generated/i18n.dart';
  2. import 'package:extended_text/extended_text.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/rendering.dart';
  5. // Minimal padding from all edges of the selection toolbar to all edges of the
  6. // viewport.
  7. const double _kToolbarScreenPadding = 8.0;
  8. const double _kToolbarHeight = 44.0;
  9. ///
  10. /// create by zmtzawqlp on 2019/8/3
  11. ///
  12. class MyExtendedMaterialTextSelectionControls
  13. extends ExtendedMaterialTextSelectionControls {
  14. TextSelectionDelegate delegate;
  15. @override
  16. Widget buildToolbar(
  17. BuildContext context,
  18. Rect globalEditableRegion,
  19. double textLineHeight,
  20. Offset position,
  21. List<TextSelectionPoint> endpoints,
  22. TextSelectionDelegate delegate,
  23. ) {
  24. assert(debugCheckHasMediaQuery(context));
  25. assert(debugCheckHasMaterialLocalizations(context));
  26. this.delegate = delegate;
  27. // The toolbar should appear below the TextField
  28. // when there is not enough space above the TextField to show it.
  29. final TextSelectionPoint startTextSelectionPoint = endpoints[0];
  30. final TextSelectionPoint endTextSelectionPoint =
  31. (endpoints.length > 1) ? endpoints[1] : null;
  32. final double x = (endTextSelectionPoint == null)
  33. ? startTextSelectionPoint.point.dx
  34. : (startTextSelectionPoint.point.dx + endTextSelectionPoint.point.dx) /
  35. 2.0;
  36. final double availableHeight = globalEditableRegion.top -
  37. MediaQuery.of(context).padding.top -
  38. _kToolbarScreenPadding;
  39. final double y = (availableHeight < _kToolbarHeight)
  40. ? startTextSelectionPoint.point.dy +
  41. globalEditableRegion.height +
  42. _kToolbarHeight +
  43. _kToolbarScreenPadding
  44. : startTextSelectionPoint.point.dy - textLineHeight * 2.0;
  45. final Offset preciseMidpoint = Offset(x, y);
  46. return ConstrainedBox(
  47. constraints: BoxConstraints.tight(globalEditableRegion.size),
  48. child: CustomSingleChildLayout(
  49. delegate: ExtendedMaterialTextSelectionToolbarLayout(
  50. MediaQuery.of(context).size,
  51. globalEditableRegion,
  52. preciseMidpoint,
  53. ),
  54. child: _TextSelectionToolbar(
  55. handleCut: canCut(delegate) ? () => handleCut(delegate) : null,
  56. handleCopy: canCopy(delegate) ? () => handleCopy(delegate) : null,
  57. handlePaste: canPaste(delegate) ? () => handlePaste(delegate) : null,
  58. handleSelectAll:
  59. canSelectAll(delegate) ? () => handleSelectAll(delegate) : null,
  60. // handleLike: () {
  61. // MessageMgr().emit('Delete Select Message', msg);
  62. // },
  63. // handleRef: canSelectAll(delegate)
  64. // ? null
  65. // : () {
  66. // MessageMgr().emit('Reply Select Message', msg);
  67. // },
  68. delegate: delegate,
  69. ),
  70. ),
  71. );
  72. }
  73. test(){
  74. handleSelectAll(delegate);
  75. }
  76. @override
  77. void goTest() {
  78. Future.delayed(Duration(milliseconds: 350),(){
  79. handleSelectAll(delegate);
  80. });
  81. }
  82. // @override
  83. // Widget buildHandle(
  84. // BuildContext context, TextSelectionHandleType type, double textHeight) {
  85. // final Widget handle = SizedBox(
  86. // width: _kHandleSize,
  87. // height: _kHandleSize,
  88. // child: Image.asset("assets/40.png"),
  89. // );
  90. //
  91. // // [handle] is a circle, with a rectangle in the top left quadrant of that
  92. // // circle (an onion pointing to 10:30). We rotate [handle] to point
  93. // // straight up or up-right depending on the handle type.
  94. // switch (type) {
  95. // case TextSelectionHandleType.left: // points up-right
  96. // return Transform.rotate(
  97. // angle: math.pi / 4.0,
  98. // child: handle,
  99. // );
  100. // case TextSelectionHandleType.right: // points up-left
  101. // return Transform.rotate(
  102. // angle: -math.pi / 4.0,
  103. // child: handle,
  104. // );
  105. // case TextSelectionHandleType.collapsed: // points up
  106. // return handle;
  107. // }
  108. // assert(type != null);
  109. // return null;
  110. // }
  111. }
  112. /// Manages a copy/paste text selection toolbar.
  113. class _TextSelectionToolbar extends StatelessWidget {
  114. const _TextSelectionToolbar(
  115. {Key key,
  116. this.handleCopy,
  117. this.handleSelectAll,
  118. this.handleCut,
  119. this.handlePaste,
  120. // this.handleRef,
  121. // this.handleLike,
  122. this.delegate})
  123. : super(key: key);
  124. final VoidCallback handleCut;
  125. final VoidCallback handleCopy;
  126. final VoidCallback handlePaste;
  127. final VoidCallback handleSelectAll;
  128. // final VoidCallback handleLike;
  129. // final VoidCallback handleRef;
  130. final TextSelectionDelegate delegate;
  131. @override
  132. Widget build(BuildContext context) {
  133. final List<Widget> items = <Widget>[];
  134. if (handleCopy != null)
  135. items.add(GestureDetector(
  136. onTap: handleCopy,
  137. child: Container(
  138. padding: EdgeInsets.fromLTRB(12, 9, 12, 9),
  139. child: Text(
  140. I18n.of(context).copy,
  141. textScaleFactor: 1.0,
  142. style: TextStyle(color: Colors.white, fontSize: 12),
  143. ),
  144. ),
  145. ));
  146. if (handleSelectAll != null)
  147. items.add(GestureDetector(
  148. onTap: handleSelectAll,
  149. child: Container(
  150. padding: EdgeInsets.fromLTRB(12, 9, 12, 9),
  151. child: Text(
  152. I18n.of(context).select_all,
  153. textScaleFactor: 1.0,
  154. style: TextStyle(color: Colors.white, fontSize: 12),
  155. ),
  156. ),
  157. ));
  158. // if (handleRef != null) {
  159. // items.add(GestureDetector(
  160. // onTap: () {
  161. // delegate.hideToolbar();
  162. // handleRef();
  163. // },
  164. // child: Container(
  165. // padding: EdgeInsets.fromLTRB(12, 9, 12, 9),
  166. // child: Text(
  167. // '回复',
  168. // textScaleFactor: 1.0,
  169. // style: TextStyle(color: Colors.white, fontSize: 12),
  170. // ),
  171. // ),
  172. // ));
  173. //}
  174. // if (handleCut != null)
  175. // items.add(FlatButton(
  176. // child: Text(localizations.cutButtonLabel), onPressed: handleCut));
  177. // if (handleCopy != null)
  178. // items.add(FlatButton(
  179. // child: Text(localizations.copyButtonLabel), onPressed: handleCopy));
  180. // if (handlePaste != null)
  181. // items.add(FlatButton(
  182. // child: Text(localizations.pasteButtonLabel),
  183. // onPressed: handlePaste,
  184. // ));
  185. // if (handleSelectAll != null)
  186. // items.add(FlatButton(
  187. // child: Text(localizations.selectAllButtonLabel),
  188. // onPressed: handleSelectAll));
  189. // if (handleLike != null)
  190. // items.add(GestureDetector(
  191. // onTap: handleLike,
  192. // child: Container(
  193. // padding: EdgeInsets.fromLTRB(12, 9, 12, 9),
  194. // child: Text(
  195. // I18n.of(context).delete,
  196. // textScaleFactor: 1.0,
  197. // style: TextStyle(color: Colors.white, fontSize: 12),
  198. // ),
  199. // ),
  200. // ));
  201. // If there is no option available, build an empty widget.
  202. if (items.isEmpty) {
  203. return Container(width: 0.0, height: 0.0);
  204. }
  205. return Material(
  206. elevation: 1.0,
  207. child: Container(
  208. child: Wrap(children: items),
  209. decoration: BoxDecoration(
  210. color: Colors.black,
  211. borderRadius: BorderRadius.all(Radius.circular(5.0))),
  212. ),
  213. );
  214. }
  215. }