LCOV - code coverage report
Current view: top level - components/align_ruler - align_ruler.dart (source / functions) Hit Total Coverage
Test: new_lcov.info Lines: 144 153 94.1 %
Date: 2021-11-22 14:23:42 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:convert';
       2             : 
       3             : import 'package:flutter/material.dart';
       4             : import 'package:flutter/services.dart';
       5             : import 'package:flutter_ume/util/constants.dart';
       6             : import 'package:flutter_ume_kit_ui/components/hit_test.dart';
       7             : import 'package:flutter_ume/flutter_ume.dart';
       8             : import 'icon.dart' as icon;
       9             : 
      10             : class AlignRuler extends StatefulWidget implements Pluggable {
      11           2 :   AlignRuler({Key? key}) : super(key: key);
      12             : 
      13           1 :   @override
      14           1 :   _AlignRulerState createState() => _AlignRulerState();
      15             : 
      16           1 :   @override
      17             :   Widget buildWidget(BuildContext? context) => this;
      18             : 
      19           1 :   @override
      20             :   ImageProvider<Object> get iconImageProvider =>
      21           2 :       MemoryImage(base64Decode(icon.iconData));
      22             : 
      23           1 :   @override
      24             :   String get name => 'AlignRuler';
      25             : 
      26           0 :   @override
      27             :   String get displayName => 'AlignRuler';
      28             : 
      29           1 :   @override
      30             :   void onTrigger() {}
      31             : }
      32             : 
      33             : class _AlignRulerState extends State<AlignRuler> {
      34             :   Size _windowSize = windowSize;
      35             :   final Size _dotSize = Size(80, 80);
      36             :   Offset _dotPosition = Offset.zero;
      37             :   BorderRadius? _radius;
      38             :   late Offset _dotOffset;
      39             :   final TextStyle _fontStyle = TextStyle(color: Colors.red, fontSize: 15);
      40             :   Size _textSize = Size.zero;
      41             :   double _toolBarY = 60.0;
      42             :   bool _switched = false;
      43             :   InspectorSelection _selection = WidgetInspectorService.instance.selection;
      44             : 
      45           1 :   @override
      46             :   void initState() {
      47           3 :     _dotPosition = _windowSize.center(Offset.zero);
      48           4 :     _radius = BorderRadius.circular(_dotSize.longestSide);
      49           3 :     _dotOffset = _dotSize.center(Offset.zero);
      50           1 :     super.initState();
      51           2 :     _textSize = _getTextSize();
      52           2 :     _selection.clear();
      53             :   }
      54             : 
      55           1 :   void _onPanUpdate(DragUpdateDetails dragDetails) {
      56           2 :     setState(() {
      57           2 :       _dotPosition = dragDetails.globalPosition;
      58             :     });
      59             :   }
      60             : 
      61           1 :   void _onPanEnd(DragEndDetails dragDetails) {
      62           1 :     if (!_switched) return;
      63           2 :     final List<RenderObject> objects = HitTest.hitTest(_dotPosition);
      64           2 :     _selection.candidates = objects;
      65             :     Offset offset = Offset.zero;
      66           2 :     for (var obj in objects) {
      67           2 :       var translation = obj.getTransformTo(null).getTranslation();
      68           5 :       Rect rect = obj.paintBounds.shift(Offset(translation.x, translation.y));
      69           2 :       if (rect.contains(_dotPosition)) {
      70             :         double dx, dy = 0.0;
      71           2 :         double perW = rect.width / 2;
      72           2 :         double perH = rect.height / 2;
      73           5 :         if (_dotPosition.dx <= perW + translation.x) {
      74           1 :           dx = translation.x;
      75             :         } else {
      76           0 :           dx = translation.x + rect.width;
      77             :         }
      78           5 :         if (_dotPosition.dy <= translation.y + perH) {
      79           0 :           dy = translation.y;
      80             :         } else {
      81           3 :           dy = translation.y + rect.height;
      82             :         }
      83           1 :         offset = Offset(dx, dy);
      84             :         break;
      85             :       }
      86             :     }
      87           2 :     setState(() {
      88           2 :       _dotPosition = offset == Offset.zero ? _dotPosition : offset;
      89           1 :       HapticFeedback.mediumImpact();
      90             :     });
      91             :   }
      92             : 
      93           0 :   void _toolBarPanUpdate(DragUpdateDetails dragDetails) {
      94           0 :     setState(() {
      95           0 :       _toolBarY = dragDetails.globalPosition.dy - 40;
      96             :     });
      97             :   }
      98             : 
      99           1 :   Size _getTextSize() {
     100           1 :     final textPainter = TextPainter(
     101             :       textDirection: TextDirection.ltr,
     102           1 :       text: TextSpan(
     103             :         text: '789.5', // for caculate size
     104           1 :         style: _fontStyle,
     105             :       ),
     106             :     );
     107           1 :     textPainter.layout();
     108           3 :     return Size(textPainter.width, textPainter.height);
     109             :   }
     110             : 
     111           1 :   void _switchChanged(bool swi) {
     112           2 :     setState(() {
     113           1 :       _switched = swi;
     114           1 :       if (!_switched) {
     115           0 :         _selection.clear();
     116             :       }
     117             :     });
     118             :   }
     119             : 
     120           1 :   @override
     121             :   Widget build(BuildContext context) {
     122           2 :     if (_windowSize.isEmpty) {
     123           0 :       _windowSize = MediaQuery.of(context).size;
     124           0 :       _dotPosition = _windowSize.center(Offset.zero);
     125             :     }
     126             :     const TextStyle style = TextStyle(fontSize: 17, color: Colors.black);
     127           1 :     Widget toolBar = Container(
     128           4 :       width: MediaQuery.of(context).size.width - 32,
     129           1 :       decoration: BoxDecoration(
     130             :           color: Colors.white,
     131           1 :           borderRadius: BorderRadius.circular(16),
     132           1 :           boxShadow: [
     133             :             const BoxShadow(
     134             :                 color: Colors.black26, blurRadius: 6, offset: Offset(2, 2))
     135             :           ]),
     136             :       padding: const EdgeInsets.only(bottom: 16, top: 12),
     137           1 :       child: Column(
     138             :         crossAxisAlignment: CrossAxisAlignment.start,
     139           1 :         children: <Widget>[
     140           1 :           Padding(
     141             :             padding: const EdgeInsets.only(left: 26, right: 26),
     142           1 :             child: Row(
     143             :               mainAxisAlignment: MainAxisAlignment.spaceAround,
     144           1 :               children: <Widget>[
     145           1 :                 Expanded(
     146           1 :                   child: Column(
     147             :                     crossAxisAlignment: CrossAxisAlignment.start,
     148           1 :                     children: <Widget>[
     149           5 :                       Text('Left: ${_dotPosition.dx.toStringAsFixed(1)}',
     150             :                           style: style),
     151           1 :                       Padding(padding: const EdgeInsets.only(top: 8)),
     152           1 :                       Text(
     153           7 :                           'Right: ${(_windowSize.width - _dotPosition.dx).toStringAsFixed(1)}',
     154             :                           style: style),
     155             :                     ],
     156             :                   ),
     157             :                 ),
     158           1 :                 Expanded(
     159           1 :                   child: Column(
     160             :                     crossAxisAlignment: CrossAxisAlignment.start,
     161           1 :                     children: <Widget>[
     162           5 :                       Text('Top: ${_dotPosition.dy.toStringAsFixed(1)}',
     163             :                           style: style),
     164           1 :                       Padding(padding: const EdgeInsets.only(top: 8)),
     165           1 :                       Text(
     166           7 :                           'Bottom: ${(_windowSize.height - _dotPosition.dy).toStringAsFixed(1)}',
     167             :                           style: style),
     168             :                     ],
     169             :                   ),
     170             :                 ),
     171             :               ],
     172             :             ),
     173             :           ),
     174           1 :           Padding(
     175             :             padding: const EdgeInsets.only(top: 12),
     176           1 :             child: Row(
     177           1 :               children: <Widget>[
     178           1 :                 Container(
     179             :                   padding: const EdgeInsets.only(left: 20),
     180             :                   height: 30,
     181           1 :                   child: Transform.scale(
     182             :                     scale: 1.3,
     183           1 :                     child: Switch(
     184           1 :                         value: _switched,
     185           1 :                         onChanged: _switchChanged,
     186             :                         activeColor: Colors.red),
     187             :                   ),
     188             :                 ),
     189           1 :                 Expanded(
     190           1 :                   child: Padding(
     191             :                     padding: const EdgeInsets.only(left: 10),
     192           1 :                     child: Text('开启后松手将会自动吸附至最近widget',
     193             :                         style: const TextStyle(
     194             :                             color: Colors.red, fontWeight: FontWeight.w500)),
     195             :                   ),
     196             :                 )
     197             :               ],
     198             :             ),
     199             :           )
     200             :         ],
     201             :       ),
     202             :     );
     203             : 
     204           5 :     double verticalLeft = _dotPosition.dx - _textSize.width;
     205           5 :     double horizontalTop = _dotPosition.dy - _textSize.height;
     206             : 
     207           1 :     return Container(
     208             :       color: Colors.transparent,
     209           3 :       height: MediaQuery.of(context).size.height,
     210           3 :       width: MediaQuery.of(context).size.height,
     211           1 :       child: Stack(
     212             :         alignment: Alignment.center,
     213           1 :         children: [
     214           1 :           Positioned(
     215             :               top: horizontalTop,
     216           7 :               left: _dotPosition.dx / 2 - _textSize.width / 2,
     217           5 :               child: Text('${_dotPosition.dx.toStringAsFixed(1)}',
     218           1 :                   style: _fontStyle)),
     219           1 :           Positioned(
     220             :               left: verticalLeft,
     221           7 :               top: _dotPosition.dy / 2 - _textSize.height / 2,
     222           5 :               child: Text('${_dotPosition.dy.toStringAsFixed(1)}',
     223           1 :                   style: _fontStyle)),
     224           1 :           Positioned(
     225           3 :               left: _dotPosition.dx +
     226           7 :                   (_windowSize.width - _dotPosition.dx) / 2 -
     227           3 :                   _textSize.width / 2,
     228             :               top: horizontalTop,
     229           1 :               child: Text(
     230           7 :                   '${(_windowSize.width - _dotPosition.dx).toStringAsFixed(1)}',
     231           1 :                   style: _fontStyle)),
     232           1 :           Positioned(
     233           3 :               top: _dotPosition.dy +
     234           7 :                   (_windowSize.height - _dotPosition.dy) / 2 -
     235           3 :                   _textSize.height / 2,
     236             :               left: verticalLeft,
     237           1 :               child: Text(
     238           7 :                   '${(_windowSize.height - _dotPosition.dy).toStringAsFixed(1)}',
     239           1 :                   style: _fontStyle)),
     240           1 :           Positioned(
     241           2 :               left: _dotPosition.dx,
     242             :               top: 0,
     243           1 :               child: Container(
     244             :                 width: 1,
     245           2 :                 height: _windowSize.height,
     246             :                 color: const Color(0xffff0000),
     247             :               )),
     248           1 :           Positioned(
     249             :               left: 0,
     250           2 :               top: _dotPosition.dy,
     251           1 :               child: Container(
     252           2 :                 width: _windowSize.width,
     253             :                 height: 1,
     254             :                 color: const Color(0xffff0000),
     255             :               )),
     256           1 :           Positioned(
     257           5 :             left: _dotPosition.dx - _dotOffset.dx,
     258           5 :             top: _dotPosition.dy - _dotOffset.dy,
     259           1 :             child: GestureDetector(
     260           1 :               onPanUpdate: _onPanUpdate,
     261           1 :               onPanEnd: _onPanEnd,
     262           1 :               child: Container(
     263           1 :                 child: Center(
     264           1 :                   child: Container(
     265           3 :                     height: _dotSize.width / 2.5,
     266           3 :                     width: _dotSize.height / 2.5,
     267           1 :                     decoration: BoxDecoration(
     268             :                         shape: BoxShape.circle,
     269           1 :                         color: Colors.red.withOpacity(0.8)),
     270             :                   ),
     271             :                 ),
     272           2 :                 height: _dotSize.height,
     273           2 :                 width: _dotSize.width,
     274           1 :                 decoration: BoxDecoration(
     275           1 :                     borderRadius: _radius,
     276           1 :                     border: Border.all(color: Colors.black, width: 2)),
     277             :               ),
     278             :             ),
     279             :           ),
     280           1 :           Positioned(
     281             :               left: 16,
     282           1 :               top: _toolBarY,
     283           1 :               child: GestureDetector(
     284           1 :                   onVerticalDragUpdate: _toolBarPanUpdate, child: toolBar)),
     285           1 :           InspectorOverlay(
     286           1 :               selection: _selection, needDescription: false, needEdges: false),
     287             :         ],
     288             :       ),
     289             :     );
     290             :   }
     291             : }

Generated by: LCOV version 1.15