Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:math' as math; | 5 import 'dart:math' as math; |
| 6 | 6 |
| 7 import 'package:sky/rendering/box.dart'; | 7 import 'package:sky/rendering/box.dart'; |
| 8 import 'package:sky/rendering/object.dart'; | 8 import 'package:sky/rendering/object.dart'; |
| 9 import 'package:sky/widgets/basic.dart'; | 9 import 'package:sky/widgets/basic.dart'; |
| 10 import 'package:sky/widgets/icon.dart'; | 10 import 'package:sky/widgets/icon.dart'; |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 } | 292 } |
| 293 return new TabBarWrapper( | 293 return new TabBarWrapper( |
| 294 children: tabs, | 294 children: tabs, |
| 295 selectedIndex: selectedIndex, | 295 selectedIndex: selectedIndex, |
| 296 backgroundColor: Theme.of(this).primary[500], | 296 backgroundColor: Theme.of(this).primary[500], |
| 297 indicatorColor: Theme.of(this).accent[200], | 297 indicatorColor: Theme.of(this).accent[200], |
| 298 textAndIcons: textAndIcons | 298 textAndIcons: textAndIcons |
| 299 ); | 299 ); |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 | |
| 303 class TabNavigatorView { | |
| 304 TabNavigatorView({ this.label, this.content }); | |
| 305 | |
| 306 final TabLabel label; | |
| 307 final Function content; | |
|
Hixie
2015/06/27 00:12:38
Function doesn't have a return type. Make a typede
hansmuller
2015/06/29 16:49:42
Thanks, that's better than the names I had in mind
| |
| 308 | |
| 309 Widget buildContent() { | |
| 310 return content != null ? content() : null; | |
|
abarth-chromium
2015/06/27 00:27:36
Should we just build unconditionally? What does i
hansmuller
2015/06/29 16:49:42
I suppose it could mean that there's no view for t
| |
| 311 } | |
| 312 } | |
| 313 | |
| 314 class TabNavigator extends Component { | |
| 315 TabNavigator({ | |
| 316 String key, | |
| 317 this.views, | |
| 318 this.selectedIndex: 0, | |
| 319 this.onChanged | |
| 320 }) : super(key: key, stateful: true); | |
| 321 | |
| 322 List<TabNavigatorView> views; | |
| 323 int selectedIndex; | |
| 324 SelectedIndexChanged onChanged; | |
| 325 | |
| 326 void syncFields(TabNavigator source) { | |
| 327 views = source.views; | |
| 328 selectedIndex = source.selectedIndex; | |
| 329 onChanged = source.onChanged; | |
| 330 } | |
| 331 | |
| 332 void _selectedTabIndexChanged(int tabIndex) { | |
| 333 setState(() { | |
| 334 selectedIndex = tabIndex; | |
| 335 }); | |
| 336 if (onChanged != null) | |
| 337 onChanged(selectedIndex); | |
|
abarth-chromium
2015/06/27 00:27:36
I'm not sure it makes sense to do both of these.
| |
| 338 } | |
| 339 | |
| 340 Widget build() { | |
| 341 assert(views != null && views.isNotEmpty); | |
| 342 assert(selectedIndex >= 0 && selectedIndex < views.length); | |
| 343 | |
| 344 TabBar tabBar = new TabBar( | |
| 345 labels: views.map((view) => view.label).toList(), | |
|
Hixie
2015/06/27 00:12:38
Why toList()?
hansmuller
2015/06/29 16:49:42
I've changed the type of TabBar.labels to Iterable
| |
| 346 onChanged: _selectedTabIndexChanged, | |
|
abarth-chromium
2015/06/27 00:27:36
If you make that change, you can just pass onChang
| |
| 347 selectedIndex: selectedIndex | |
| 348 ); | |
| 349 | |
| 350 Widget content = views[selectedIndex].buildContent(); | |
| 351 return new Flex( | |
| 352 <Widget>[tabBar, new Flexible(child: content)], | |
|
Hixie
2015/06/27 00:12:38
We don't usually bother type-annotating the childr
hansmuller
2015/06/29 16:49:41
OK. As you know, without the annotation code like
| |
| 353 direction: FlexDirection.vertical | |
| 354 ); | |
| 355 } | |
| 356 } | |
| OLD | NEW |