toggleable.dart 2.12 KB
Newer Older
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'package:flutter/animation.dart';
import 'package:flutter/gestures.dart';
7 8 9 10 11

import 'binding.dart';
import 'box.dart';
import 'object.dart';
import 'proxy_box.dart';
12

Hixie's avatar
Hixie committed
13
typedef void ValueChanged<T>(T value);
14 15 16 17 18 19 20 21

const Duration _kToggleDuration = const Duration(milliseconds: 200);

// RenderToggleable is a base class for material style toggleable controls with
// toggle animations. It handles storing the current value, dispatching
// ValueChanged on a tap gesture and driving a changed animation. Subclasses are
// responsible for painting.
abstract class RenderToggleable extends RenderConstrainedBox {
22 23 24 25 26 27
  RenderToggleable({
    bool value,
    Size size,
    this.onChanged
  }) : _value = value,
       super(additionalConstraints: new BoxConstraints.tight(size)) {
28
    _performance = new ValuePerformance<double>(
29
      variable: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeIn, reverseCurve: Curves.easeOut),
Hixie's avatar
Hixie committed
30 31 32
      duration: _kToggleDuration,
      progress: _value ? 1.0 : 0.0
    )..addListener(markNeedsPaint);
33 34
  }

35 36 37 38 39 40 41 42 43 44 45
  bool get value => _value;
  bool _value;
  void set value(bool value) {
    if (value == _value)
      return;
    _value = value;
    performance.play(value ? AnimationDirection.forward : AnimationDirection.reverse);
  }

  ValueChanged<bool> onChanged;

46 47
  ValuePerformance<double> get performance => _performance;
  ValuePerformance<double> _performance;
Hixie's avatar
Hixie committed
48 49 50

  double get position => _performance.value;

51 52 53 54 55
  TapGestureRecognizer _tap;

  void attach() {
    super.attach();
    _tap = new TapGestureRecognizer(
56
      router: FlutterBinding.instance.pointerRouter,
57 58 59 60
      onTap: _handleTap
    );
  }

61
  void detach() {
62 63 64 65 66
    _tap.dispose();
    _tap = null;
    super.detach();
  }

67 68 69
  void handleEvent(InputEvent event, BoxHitTestEntry entry) {
    if (event.type == 'pointerdown' && onChanged != null)
      _tap.addPointer(event);
70 71
  }

72 73 74
  void _handleTap() {
    if (onChanged != null)
      onChanged(!_value);
75
  }
Adam Barth's avatar
Adam Barth committed
76 77

  bool hitTestSelf(Point position) => true;
78
}