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

import 'dart:math' as math;

7 8
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
9

10
import '../rendering/src/sector_layout.dart';
11 12

RenderBox initCircle() {
13
  return RenderBoxToRenderSectorAdapter(
14
    innerRadius: 25.0,
15
    child: RenderSectorRing(padding: 0.0)
16 17 18
  );
}

19
class SectorApp extends StatefulWidget {
20
  @override
21
  SectorAppState createState() => SectorAppState();
Hixie's avatar
Hixie committed
22 23 24
}

class SectorAppState extends State<SectorApp> {
25

Hixie's avatar
Hixie committed
26
  final RenderBoxToRenderSectorAdapter sectors = initCircle();
27
  final math.Random rand = math.Random(1);
28

29 30
  List<double> wantedSectorSizes = <double>[];
  List<double> actualSectorSizes = <double>[];
31
  double get currentTheta => wantedSectorSizes.fold<double>(0.0, (double total, double value) => total + value);
32

33
  void addSector() {
34 35 36
    final double currentTheta = this.currentTheta;
    if (currentTheta < kTwoPi) {
      double deltaTheta;
37
      if (currentTheta >= kTwoPi - (math.pi * 0.2 + 0.05))
38 39
        deltaTheta = kTwoPi - currentTheta;
      else
40
        deltaTheta = math.pi * rand.nextDouble() / 5.0 + 0.05;
41 42 43
      wantedSectorSizes.add(deltaTheta);
      updateEnabledState();
    }
44 45 46
  }

  void removeSector() {
47 48 49 50 51 52 53 54 55 56
    if (wantedSectorSizes.isNotEmpty) {
      wantedSectorSizes.removeLast();
      updateEnabledState();
    }
  }

  void doUpdates() {
    int index = 0;
    while (index < actualSectorSizes.length && index < wantedSectorSizes.length && actualSectorSizes[index] == wantedSectorSizes[index])
      index += 1;
57
    final RenderSectorRing ring = sectors.child;
58 59 60 61 62
    while (index < actualSectorSizes.length) {
      ring.remove(ring.lastChild);
      actualSectorSizes.removeLast();
    }
    while (index < wantedSectorSizes.length) {
63 64
      final Color color = Color(((0xFF << 24) + rand.nextInt(0xFFFFFF)) | 0x808080);
      ring.add(RenderSolidColor(color, desiredDeltaTheta: wantedSectorSizes[index]));
65 66 67
      actualSectorSizes.add(wantedSectorSizes[index]);
      index += 1;
    }
68 69 70
  }

  static RenderBox initSector(Color color) {
71 72 73 74 75
    final RenderSectorRing ring = RenderSectorRing(padding: 1.0);
    ring.add(RenderSolidColor(const Color(0xFF909090), desiredDeltaTheta: kTwoPi * 0.15));
    ring.add(RenderSolidColor(const Color(0xFF909090), desiredDeltaTheta: kTwoPi * 0.15));
    ring.add(RenderSolidColor(color, desiredDeltaTheta: kTwoPi * 0.2));
    return RenderBoxToRenderSectorAdapter(
76 77 78 79 80 81 82
      innerRadius: 5.0,
      child: ring
    );
  }
  RenderBoxToRenderSectorAdapter sectorAddIcon = initSector(const Color(0xFF00DD00));
  RenderBoxToRenderSectorAdapter sectorRemoveIcon = initSector(const Color(0xFFDD0000));

Hixie's avatar
Hixie committed
83 84
  bool _enabledAdd = true;
  bool _enabledRemove = false;
85 86
  void updateEnabledState() {
    setState(() {
87 88
      _enabledAdd = currentTheta < kTwoPi;
      _enabledRemove = wantedSectorSizes.isNotEmpty;
89 90 91 92
    });
  }

  Widget buildBody() {
93
    return Column(
94
      children: <Widget>[
95
        Container(
96
          padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 25.0),
97
          child: Row(
98
            children: <Widget>[
99
              RaisedButton(
100
                onPressed: _enabledAdd ? addSector : null,
101 102
                child: IntrinsicWidth(
                  child: Row(
103
                    children: <Widget>[
104
                      Container(
105 106
                        padding: const EdgeInsets.all(4.0),
                        margin: const EdgeInsets.only(right: 10.0),
107
                        child: WidgetToRenderBoxAdapter(renderBox: sectorAddIcon)
108
                      ),
109
                      const Text('ADD SECTOR'),
110 111
                    ]
                  )
112
                )
113
              ),
114
              RaisedButton(
115
                onPressed: _enabledRemove ? removeSector : null,
116 117
                child: IntrinsicWidth(
                  child: Row(
118
                    children: <Widget>[
119
                      Container(
120 121
                        padding: const EdgeInsets.all(4.0),
                        margin: const EdgeInsets.only(right: 10.0),
122
                        child: WidgetToRenderBoxAdapter(renderBox: sectorRemoveIcon)
123
                      ),
124
                      const Text('REMOVE SECTOR'),
125 126
                    ]
                  )
127 128
                )
              ),
129
            ],
130
            mainAxisAlignment: MainAxisAlignment.spaceAround
131 132
          )
        ),
133 134
        Expanded(
          child: Container(
135
            margin: const EdgeInsets.all(8.0),
136 137
            decoration: BoxDecoration(
              border: Border.all()
138
            ),
139
            padding: const EdgeInsets.all(8.0),
140
            child: WidgetToRenderBoxAdapter(
141 142 143
              renderBox: sectors,
              onBuild: doUpdates
            )
144 145 146
          )
        ),
      ],
147
      mainAxisAlignment: MainAxisAlignment.spaceBetween
148 149 150
    );
  }

151
  @override
Hixie's avatar
Hixie committed
152
  Widget build(BuildContext context) {
153 154
    return MaterialApp(
      theme: ThemeData.light(),
Hixie's avatar
Hixie committed
155
      title: 'Sector Layout',
156 157
      home: Scaffold(
        appBar: AppBar(
158
          title: const Text('Sector Layout in a Widget Tree')
159 160 161
        ),
        body: buildBody()
      )
162 163 164 165 166
    );
  }
}

void main() {
167
  runApp(SectorApp());
168
}