Skip to content

Commit

Permalink
Merge pull request #23 from kevlatus/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
kevlatus authored Dec 26, 2020
2 parents 39c33d0 + bf510f1 commit af66a4e
Show file tree
Hide file tree
Showing 24 changed files with 724 additions and 254 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [0.2.0] - 2020-12-26

feat: add styling strategies for individual items

## [0.1.1] - 2020-12-20

docs: add basic dartdoc and README documentation
Expand Down
31 changes: 8 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Then import and use the [FortuneWidget](https://pub.dev/documentation/flutter_fo
import 'package:flutter/material.dart';
import 'package:flutter_fortune_wheel/flutter_fortune_wheel.dart';
FortuneWidget(
FortuneWidget.wheel(
selected: 0,
items: [
FortuneItem(child: Text('Han Solo')),
Expand All @@ -37,27 +37,10 @@ The wheel of fortune is the most iconic visualization.
<img src="https://raw.githubusercontent.com/kevlatus/flutter_fortune_wheel/main/images/img-wheel-anim.gif">
</p>

Unfortunately, its alternating slice colors are only suitable, when there is an even number of items to be displayed.
Furthermore, it is not the best solution when vertical screen space is scarse. Therefore the FortuneWidget example above automatically switches between the fortune wheel and
fortune bar depending on the number of items and available space.

You can still use a fortune wheel under those conditions by instantiating it directly:

```dart
import 'package:flutter/material.dart';
import 'package:flutter_fortune_wheel/flutter_fortune_wheel.dart';
FortuneWidget.wheel(
selected: 0,
items: [
FortuneItem(child: Text('Han Solo')),
FortuneItem(child: Text('Yoda')),
FortuneItem(child: Text('Obi-Wan Kenobi')),
],
)
```
Unfortunately, it is not the best solution when available vertical screen space is small.

The fortune bar is an alternative visualization, which is smaller in the vertical direction, but is supposed to take the full screen width. See below for an example:
The fortune bar is an alternative visualization, which is smaller in the vertical direction,
but is supposed to take the full screen width. See below for an example:

<p align="center">
<img src="https://raw.githubusercontent.com/kevlatus/flutter_fortune_wheel/main/images/img-bar-anim.gif">
Expand All @@ -81,5 +64,7 @@ FortuneWidget.bar(

Contributions are much appreciated.

If you have any ideas for alternative visualizations, feel free to [open a pull request](https://github.com/kevlatus/flutter_fortune_wheel/pulls) or
[raise an issue](https://github.com/kevlatus/flutter_fortune_wheel/issues). The same holds for any requests regarding existing widgets.
If you have any ideas for alternative visualizations, feel free to
[open a pull request](https://github.com/kevlatus/flutter_fortune_wheel/pulls) or
[raise an issue](https://github.com/kevlatus/flutter_fortune_wheel/issues).
The same holds for any requests regarding existing widgets.
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class _ExamplePageState extends State<ExamplePage> {
child: Column(
children: [
Expanded(
child: FortuneWidget(
child: FortuneWidget.wheel(
selected: selected,
items: [
for (var it in items) FortuneItem(child: Text(it)),
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.1.1"
version: "0.2.0"
flutter_hooks:
dependency: transitive
description:
Expand Down
6 changes: 2 additions & 4 deletions lib/flutter_fortune_wheel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
/// for its source code and community
library flutter_fortune_wheel;

export 'package:flutter_fortune_wheel/src/animations.dart'
show FortuneAnimation;
export 'package:flutter_fortune_wheel/src/fortune_widget.dart';
export 'package:flutter_fortune_wheel/src/bar/bar.dart';
export 'package:flutter_fortune_wheel/src/core/core.dart';
export 'package:flutter_fortune_wheel/src/indicators/indicators.dart';
export 'package:flutter_fortune_wheel/src/wheel/wheel.dart';
export 'package:flutter_fortune_wheel/src/util.dart' show Fortune;
export 'package:flutter_fortune_wheel/src/util/util.dart' show Fortune;
8 changes: 3 additions & 5 deletions lib/src/bar/bar.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import 'dart:math' as Math;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_fortune_wheel/src/core/core.dart';
import 'package:flutter_fortune_wheel/src/indicators/indicators.dart';

import '../animations.dart';
import '../fortune_widget.dart';
import 'package:flutter_fortune_wheel/src/util/util.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

part 'fortune_bar.dart';

Expand Down
28 changes: 22 additions & 6 deletions lib/src/bar/fortune_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class FortuneBar extends HookWidget implements FortuneWidget {
),
];

static const StyleStrategy kDefaultStyleStrategy =
const StyleStrategy.uniform(borderWidth: 4);

/// Requires this widget to have exactly this height.
final double height;

Expand Down Expand Up @@ -45,12 +48,18 @@ class FortuneBar extends HookWidget implements FortuneWidget {
/// {@macro flutter_fortune_wheel.FortuneWidget.onAnimationEnd}
final VoidCallback onAnimationEnd;

/// {@macro flutter_fortune_wheel.FortuneWidget.styleStrategy}
final StyleStrategy styleStrategy;

/// If this value is true, this widget expands to the screen width and ignores
/// width constraints imposed by parent widgets.
///
/// This is disabled by default.
final bool fullWidth;

/// {@macro flutter_fortune_wheel.FortuneWidget.animateFirst}
final bool animateFirst;

Offset _itemOffset({
int itemIndex,
double animationProgress,
Expand Down Expand Up @@ -93,6 +102,8 @@ class FortuneBar extends HookWidget implements FortuneWidget {
this.items,
this.indicators = kDefaultIndicators,
this.fullWidth = false,
this.styleStrategy = kDefaultStyleStrategy,
this.animateFirst = true,
}) : super(key: key);

@override
Expand All @@ -104,33 +115,35 @@ class FortuneBar extends HookWidget implements FortuneWidget {
);
final AnimationFunc animFunc = getAnimationFunc(animationType);

// TODO: refactor: implement shared fortune animation hook
Future<void> animate() async {
if (animationCtrl.isAnimating) {
return;
}

if (onAnimationStart != null) {
await Future.delayed(Duration.zero, onAnimationStart);
await Future.microtask(onAnimationStart);
}

await animFunc(animationCtrl);

if (onAnimationEnd != null) {
await Future.delayed(Duration.zero, onAnimationEnd);
await Future.microtask(onAnimationEnd);
}
}

useEffect(() {
animate();
if (animateFirst) animate();
return null;
}, []);

useValueChanged(selected, (_, __) {
animate();
useValueChanged(selected, (_, __) async {
await animate();
});

return LayoutBuilder(
builder: (context, constraints) {
final theme = Theme.of(context);
final visibleItemCount = Math.min(3, items.length);
final screenSize = MediaQuery.of(context).size;
final width = fullWidth ? screenSize.width : constraints.maxWidth;
Expand Down Expand Up @@ -159,7 +172,10 @@ class FortuneBar extends HookWidget implements FortuneWidget {
itemWidth: itemWidth,
),
child: _FortuneBarItem(
item: items[i],
child: items[i].child,
style: items[i].style ??
styleStrategy.getItemStyle(
theme, i, items.length),
width: itemWidth,
height: height,
),
Expand Down
32 changes: 12 additions & 20 deletions lib/src/bar/item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,40 @@ part of 'bar.dart';
class _FortuneBarItem extends StatelessWidget {
final double width;
final double height;
final FortuneItem item;
final Widget child;
final FortuneItemStyle style;

const _FortuneBarItem({
Key key,
@required this.item,
@required this.child,
@required this.width,
@required this.height,
@required this.style,
}) : super(key: key);

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);

final fillColor = item.color ??
Color.alphaBlend(
theme.primaryColor.withOpacity(0.4),
theme.colorScheme.surface,
);
final borderColor = item.borderColor ?? theme.primaryColor;
final borderWidth = item.borderWidth ?? 4;

return Container(
width: width,
height: height,
decoration: BoxDecoration(
border: Border.symmetric(
horizontal: BorderSide(
color: borderColor,
width: borderWidth / 2,
color: style.borderColor,
width: style.borderWidth / 2,
),
vertical: BorderSide(
color: borderColor,
width: borderWidth / 4,
color: style.borderColor,
width: style.borderWidth / 4,
),
),
color: fillColor,
color: style.color,
),
child: Center(
child: DefaultTextStyle(
textAlign: TextAlign.center,
style: TextStyle(color: theme.colorScheme.onSurface),
child: item.child,
textAlign: style.textAlign,
style: style.textStyle,
child: child,
),
),
);
Expand Down
11 changes: 11 additions & 0 deletions lib/src/core/animations.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
part of 'core.dart';

/// The type of animation, which is used when the value of
/// [FortuneWidget.selected] changes.
enum FortuneAnimation {
/// Animate to the [FortuneWidget.selected] item using a spinning animation.
Spin,
// TODO: Move,
/// Directly show the [FortuneWidget.selected] item without animating.
None,
}
13 changes: 13 additions & 0 deletions lib/src/core/core.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_fortune_wheel/src/bar/bar.dart';
import 'package:flutter_fortune_wheel/src/indicators/indicators.dart';
import 'package:flutter_fortune_wheel/src/wheel/wheel.dart';
import 'package:quiver/core.dart';

part 'animations.dart';

part 'fortune_item.dart';

part 'fortune_widget.dart';

part 'styling.dart';
27 changes: 27 additions & 0 deletions lib/src/core/fortune_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
part of 'core.dart';

/// A [FortuneItem] represents a value, which is chosen during a selection
/// process and displayed within a [FortuneWidget].
///
/// See also:
/// * [FortuneWidget]
@immutable
class FortuneItem {
final FortuneItemStyle style;

/// A widget to be rendered within this item.
final Widget child;

const FortuneItem({
this.style,
@required this.child,
}) : assert(child != null);

@override
int get hashCode => hash2(child, style);

@override
bool operator ==(Object other) {
return other is FortuneItem && style == other.style && child == other.child;
}
}
Loading

0 comments on commit af66a4e

Please sign in to comment.