added starting code for add form, main screen and db

This commit is contained in:
andrei 2021-11-02 21:32:21 -04:00
parent 283486936c
commit 501c937490
9 changed files with 282 additions and 54 deletions

21
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,21 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "boxchecker",
"request": "launch",
"type": "dart",
"program": "lib/box_checker.dart",
"flutterMode": "debug"
},
{
"name": "boxchecker (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
}
]
}

67
lib/add_form.dart Normal file
View File

@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'data_util.dart' as data;
class AddForm extends StatelessWidget {
AddForm({Key? key, required this.type}) : super(key: key);
final _formKey = GlobalKey<FormState>();
final data.Page type;
int _templatChoice = -1;
final FocusNode _TemplateFocusNode = FocusNode();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Add ' +
((type == data.Page.lists)
? 'Check List'
: (type == data.Page.templates)
? 'Template'
: ''),
),
),
body: Container(
margin: const EdgeInsets.all(10),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
onFieldSubmitted: (value) {
FocusScope.of(context).requestFocus(_TemplateFocusNode);
},
decoration: const InputDecoration(labelText: 'Label')),
DropdownButtonFormField(
focusNode: _TemplateFocusNode,
value: _templatChoice,
onChanged: (value) {
setState() {
_templatChoice = value as int;
}
},
decoration:
const InputDecoration(labelText: "Starting Template"),
items: const [
// TODO get templates from database
DropdownMenuItem<int>(child: Text("None"), value: -1),
DropdownMenuItem<int>(child: Text("1"), value: 0),
],
)
],
),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.save_alt),
onPressed: () {
// TODO implement adding list to database
Navigator.pop(context); // TODO replace route with checklist page
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}

72
lib/box_checker.dart Normal file
View File

@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'add_form.dart';
import 'data_util.dart' as data;
void main() {
runApp(const BoxChecker());
}
class BoxChecker extends StatelessWidget {
const BoxChecker({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(brightness: Brightness.dark),
themeMode: ThemeMode.dark,
home: const MainListPage(title: 'BoxChecker'),
);
}
}
class MainListPage extends StatefulWidget {
const MainListPage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MainListPage> createState() => _MainListPageState();
}
class _MainListPageState extends State<MainListPage> {
int _selectedPage = data.Page.lists.index;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
AddForm(type: data.Page.values[_selectedPage])));
}, // TODO Implement add button
tooltip: 'Add List',
child: const Icon(Icons.add),
),
body: ListView.builder(itemBuilder: (context, index) {
return ListTile(); // TODO Implement tile rendering
}),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedPage,
onTap: (index) {
setState(() {
_selectedPage = index;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.checklist),
label: "Lists",
),
BottomNavigationBarItem(
icon: Icon(Icons.folder_open),
label: "Templates",
),
]));
}
}

44
lib/data_util.dart Normal file
View File

@ -0,0 +1,44 @@
enum Page { lists, templates }
class List {
List(this.id, this.name, {this.isTemplate});
int id;
String name;
bool? isTemplate;
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
map["id"] = this.id;
map["list_name"] = this.name;
if (isTemplate != null) map["is_template"] = this.isTemplate as int;
return map;
}
static List fromMap(Map<String, dynamic> map) {
return List(map["id"], map["list_name"], isTemplate: map["is_template"]);
}
}
class Check {
Check(this.id, this.text, this.value, {this.listID});
int id;
String text;
bool value;
int? listID;
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
map["id"] = this.id;
map["check_text"] = this.text;
map["value"] = this.value as int;
if (listID != null) map["list_id"] = this.listID as int;
return map;
}
static Check fromMap(Map<String, dynamic> map) {
return Check(map["id"], map["check_text"], map["value"],
listID: map["list_id"]);
}
}

54
lib/db_helper.dart Normal file
View File

@ -0,0 +1,54 @@
import "package:sqflite/sqflite.dart";
import "package:sqflite/sqlite_api.dart";
import "package:path/path.dart";
class DBHelper {
DBHelper._();
static DBHelper dbHelper = DBHelper._();
late Database _database;
Future<Database> get database async {
_database = await _createDatabase();
return _database;
}
Future<Database> _createDatabase() async {
Database database =
await openDatabase(join(await getDatabasesPath(), 'mydb.db'),
onCreate: (Database db, int version) {
db.execute("""
CREATE TABLE List(
id INTEGER PRIMARY KEY AUTOINCREMENT,
list_name TEXT
is_template int2
)
""");
db.execute("""
CREATE TABLE Check(
id INTEGER PRIMARY KEY AUTOINCREMENT,
check_text TEXT,
value int2,
list_id INTEGER
)
""");
}, version: 1);
return database;
}
Future<Map<String, dynamic>> getAllLists() async {
Database db = await database;
return db.query("List", where: "is_template = ?", whereArgs: ['0'])
as Map<String, dynamic>;
}
Future<Map<String, dynamic>> getAllTemplates() async {
Database db = await database;
return db.query("List", where: "is_template = ?", whereArgs: ['1'])
as Map<String, dynamic>;
}
}

View File

@ -1,53 +0,0 @@
import 'package:flutter/material.dart';
void main() {
runApp(const BoxChecker());
}
class BoxChecker extends StatelessWidget {
const BoxChecker({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(brightness: Brightness.dark),
themeMode: ThemeMode.dark,
home: const MainListPage(title: 'BoxChecker'),
);
}
}
class MainListPage extends StatefulWidget {
const MainListPage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MainListPage> createState() => _MainListPageState();
}
class _MainListPageState extends State<MainListPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [
IconButton(
onPressed: () {}, // TODO implement dropdown meny for more options
icon: const Icon(Icons.more_vert_rounded),
tooltip: 'More Options',
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {}, // TODO Implement add button
tooltip: 'Add List',
child: const Icon(Icons.add),
),
body: ListView.builder(itemBuilder: (context, index) {
return ListTile(); // TODO Implement tile rendering
}),
);
}
}

View File

@ -114,6 +114,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
sqflite:
dependency: "direct main"
description:
name: sqflite
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0+4"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1+1"
stack_trace:
dependency: transitive
description:
@ -135,6 +149,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
synchronized:
dependency: transitive
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
term_glyph:
dependency: transitive
description:
@ -165,3 +186,4 @@ packages:
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.10.0"

View File

@ -29,6 +29,7 @@ environment:
dependencies:
flutter:
sdk: flutter
sqflite: ^2.0.0+4
# The following adds the Cupertino Icons font to your application.

View File

@ -8,7 +8,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:boxchecker/main.dart';
import 'package:boxchecker/box_checker.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {