Skip to content

Commit

Permalink
Start of sliver app bar for improved design
Browse files Browse the repository at this point in the history
  • Loading branch information
fuzzybinary committed Mar 23, 2021
1 parent 726a12d commit a30ee2a
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 114 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
local.properties
42 changes: 42 additions & 0 deletions lib/game_screen/game_sceen_app_bar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:flutter/material.dart';

@immutable
class GameScreenAppBar extends SliverPersistentHeaderDelegate {
final double expandedHeight;

GameScreenAppBar({required this.expandedHeight});

@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final theme = Theme.of(context);
return Stack(
fit: StackFit.expand,
children: [
Container(
decoration: BoxDecoration(color: Colors.lightBlue),
child: Align(
alignment: Alignment.topCenter,
child: Text("Lost Cities Scoring Helper",
style: theme.textTheme.headline6!.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
)),
),
),
Placeholder()
],
);
}

@override
double get maxExtent => 200;

@override
double get minExtent => kToolbarHeight;

@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return true;
}
}
48 changes: 33 additions & 15 deletions lib/game_screen/game_screen.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import 'package:flutter/material.dart';
import 'package:flutter_match/game_screen/game_sceen_app_bar.dart';
import 'package:flutter_match/game_screen/round_view.dart';
import 'package:flutter_match/scoring_screen/scoring_screen.dart';
import 'package:flutter_match/tflite/classifier.dart';

import 'game_screen_bloc.dart';

class GameScreen extends StatefulWidget {
final Classifier classifier;

GameScreen(this.classifier);

@override
State<StatefulWidget> createState() => _GameScreenState();
}
Expand All @@ -14,27 +20,39 @@ class _GameScreenState extends State<GameScreen> {

void _onRequestScore(BuildContext context, int player, int expidition) {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ScoringScreen();
return ScoringScreen(widget.classifier);
}));
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Lost Cities Scoring Helper"),
),
body: ListView.separated(
separatorBuilder: (context, index) {
return Divider();
},
itemCount: _bloc.rounds.length,
itemBuilder: (context, index) {
return RoundView(
round: _bloc.rounds[index],
onScoreRequested: (p, e) => _onRequestScore(context, p, e),
);
},
body: SafeArea(
child: CustomScrollView(
slivers: [
SliverPersistentHeader(
delegate: GameScreenAppBar(expandedHeight: 200),
pinned: true,
),
// Create a SliverList.
SliverList(
// Use a delegate to build items as they're scrolled on screen.
delegate: SliverChildBuilderDelegate(
// The builder function returns a ListTile with a title that
// displays the index of the current item.
(context, index) {
return RoundView(
roundNumber: index,
round: _bloc.rounds[index],
onScoreRequested: (p, e) => _onRequestScore(context, p, e),
);
},
// Builds 1000 ListTiles
childCount: _bloc.rounds.length,
),
)
],
),
),
);
}
Expand Down
43 changes: 39 additions & 4 deletions lib/game_screen/round_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,35 @@ typedef ScoreCallback = void Function(int player, int expidition);

@immutable
class RoundView extends StatelessWidget {
final int roundNumber;
final GameRound round;
final ScoreCallback onScoreRequested;

RoundView({Key? key, required this.round, required this.onScoreRequested})
RoundView(
{Key? key,
required this.roundNumber,
required this.round,
required this.onScoreRequested})
: super(key: key);

Widget _buildPlayerScore(
{required ThemeData theme,
required int playerNumber,
required int score}) {
return Container(
padding: EdgeInsets.all(5),
child: Column(
children: [
Text("Player $playerNumber"),
Text(
score.toString(),
style: theme.textTheme.headline3,
)
],
),
);
}

@override
Widget build(BuildContext context) {
final List<Color> expiditionColors = [
Expand All @@ -46,17 +69,25 @@ class RoundView extends StatelessWidget {
Colors.redAccent
];

final theme = Theme.of(context);

return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Round $roundNumber", style: theme.textTheme.headline4),
Container(
padding: EdgeInsets.fromLTRB(8, 0, 30, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Player 1 - Total Score: ${round.player1Score}"),
Row(
children: [
_buildPlayerScore(
theme: theme,
playerNumber: 1,
score: round.player1Score,
),
for (int i = 0; i < 5; ++i)
RoundButton(
color: expiditionColors[i],
Expand All @@ -72,15 +103,19 @@ class RoundView extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text("Player 2 - Total Score: ${round.player2Score}"),
Row(
children: [
for (int i = 0; i < 5; ++i)
RoundButton(
color: expiditionColors[i],
score: round.player2Scores[i],
onPressed: () => onScoreRequested(1, i),
)
),
_buildPlayerScore(
theme: theme,
playerNumber: 2,
score: round.player2Score,
),
],
),
],
Expand Down
82 changes: 4 additions & 78 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_match/game_screen/game_screen.dart';
import 'package:flutter_match/camera_view.dart';
import 'package:flutter_match/classification_box.dart';
import 'package:flutter_match/tflite/classifier.dart';

void main() {
Expand All @@ -26,73 +23,14 @@ class MyApp extends StatelessWidget {
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);

// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.

// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".

final String? title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
bool _isCameraOpen = false;

bool _classifying = false;
Classifier? _classifier;

List<ClassificationResult>? _classifications;

void _loadClassifier() async {
_classifier = Classifier();
await _classifier?.start();
}

void _onCameraButtonPressed() {
_classifications = null;
setState(() {
_isCameraOpen = !_isCameraOpen;
});
}

void _onCameraData(CameraImage cameraImage) async {
if (_classifier != null && _classifier!.ready) {
if (_classifying) {
return;
}

_classifying = true;

var classifications = await _classifier!.classify(cameraImage);
print(classifications);
_classifying = false;

setState(() {
_classifications = classifications;
});
}
}

void _classifySample() async {
if (_classifier != null && _classifier!.ready) {
if (_classifying) {
return;
}

_classifying = true;

var classifications = await _classifier!.classifyAsset('test_image.jpg');
print(classifications);

_classifying = false;
}
}
Classifier _classifier = Classifier();

@override
void initState() {
Expand All @@ -101,24 +39,12 @@ class _MyHomePageState extends State<MyHomePage> {
_loadClassifier();
}

Widget _cameraViewStack(BuildContext context) {
final boxes = _classifications?.map((c) {
return ClassificationBox(
location: c.rect,
classification: c,
);
}).toList();

return CameraView(
onCameraData: _onCameraData,
child: Stack(
children: boxes ?? [],
),
);
void _loadClassifier() async {
await _classifier.start();
}

@override
Widget build(BuildContext context) {
return GameScreen();
return GameScreen(_classifier);
}
}
26 changes: 9 additions & 17 deletions lib/scoring_screen/scoring_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import '../camera_view.dart';
import '../classification_box.dart';

class ScoringScreen extends StatefulWidget {
final Classifier classifier;

ScoringScreen(this.classifier);

@override
State<StatefulWidget> createState() => _ScoringState();
}
Expand All @@ -15,24 +19,18 @@ class _ScoringState extends State<ScoringScreen> {
ScoringBloc _bloc = ScoringBloc();

bool _classifying = false;
Classifier? _classifier;

List<ClassificationResult>? _classifications;

void _loadClassifier() async {
_classifier = Classifier();
await _classifier?.start();
}

void _onCameraData(CameraImage cameraImage) async {
if (_classifier != null && _classifier!.ready) {
if (widget.classifier.ready) {
if (_classifying) {
return;
}

_classifying = true;

var classifications = await _classifier!.classify(cameraImage);
var classifications = await widget.classifier.classify(cameraImage);
print(classifications);
_classifying = false;

Expand All @@ -45,27 +43,21 @@ class _ScoringState extends State<ScoringScreen> {
}

void _classifySample() async {
if (_classifier != null && _classifier!.ready) {
if (widget.classifier.ready) {
if (_classifying) {
return;
}

_classifying = true;

var classifications = await _classifier!.classifyAsset('test_image.jpg');
var classifications =
await widget.classifier.classifyAsset('test_image.jpg');
print(classifications);

_classifying = false;
}
}

@override
void initState() {
super.initState();

_loadClassifier();
}

void todo() {}

Widget _scoringButton(String score, bool isOn) {
Expand Down

0 comments on commit a30ee2a

Please sign in to comment.