load on all notes page all available .dbnote files and display them

reopen file on tile click
This commit is contained in:
lukas-heiligenbrunner 2022-10-29 21:39:08 +02:00
parent 8ea4dc281e
commit 7baef13eae
10 changed files with 145 additions and 65 deletions

View File

@ -1,6 +1,9 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:notes/icon_material_button.dart'; import 'package:notes/icon_material_button.dart';
import 'package:notes/note_tile.dart'; import 'package:notes/note_tile.dart';
import 'package:notes/savesystem/path.dart';
class AllNotesPage extends StatefulWidget { class AllNotesPage extends StatefulWidget {
const AllNotesPage({Key? key}) : super(key: key); const AllNotesPage({Key? key}) : super(key: key);
@ -10,6 +13,8 @@ class AllNotesPage extends StatefulWidget {
} }
class _AllNotesPageState extends State<AllNotesPage> { class _AllNotesPageState extends State<AllNotesPage> {
List<NoteTileData> tileData = [];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
@ -63,9 +68,35 @@ class _AllNotesPageState extends State<AllNotesPage> {
crossAxisCount: 5, crossAxisCount: 5,
), ),
padding: const EdgeInsets.all(2), padding: const EdgeInsets.all(2),
itemBuilder: (BuildContext context, int index) => const NoteTile(), itemBuilder: (BuildContext context, int idx) =>
itemCount: 3, NoteTile(data: tileData[idx]),
itemCount: tileData.length,
), ),
); );
} }
@override
void initState() {
super.initState();
loadAllNotes();
}
Future<void> loadAllNotes() async {
final path = await getSavePath();
final dta = await path
.list()
.where((fsentity) => fsentity.path.endsWith('.dbnote'))
.asyncMap((fsentity) async {
final lastmodified = (await fsentity.stat()).modified;
final filename = fsentity.path.split(Platform.pathSeparator).last;
final name = filename.substring(0, filename.length - 7);
return NoteTileData(name, filename, lastmodified);
}).toList();
dta.sort(
(a, b) => a.lastModified.isAfter(b.lastModified) ? -1 : 1,
);
setState(() {
tileData = dta;
});
}
} }

View File

@ -9,6 +9,7 @@ class Stroke {
double _maxy = double.negativeInfinity; double _maxy = double.negativeInfinity;
final int id; final int id;
final Color color;
@override @override
String toString() { String toString() {
@ -33,8 +34,8 @@ class Stroke {
return Rect.fromPoints(Offset(_minx, _miny), Offset(_maxx, _maxy)); return Rect.fromPoints(Offset(_minx, _miny), Offset(_maxx, _maxy));
} }
Stroke.fromPoints(this.points, this.id); Stroke.fromPoints(this.points, this.id, this.color);
Stroke(this.id); Stroke(this.id, this.color);
} }
class Point { class Point {

View File

@ -1,6 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'dart:ui'; import 'dart:ui';
import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:fluentui_system_icons/fluentui_system_icons.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:notes/savesystem/note_file.dart'; import 'package:notes/savesystem/note_file.dart';
import 'my_painter.dart'; import 'my_painter.dart';
@ -133,9 +134,11 @@ class _DrawingPageState extends State<DrawingPage> {
return; return;
} }
controller.pointMoveEvent(pos, event.kind, event.tilt); controller.pointMoveEvent(pos, event);
if (event.kind == PointerDeviceKind.touch) { if (event.kind == PointerDeviceKind.touch ||
(event.kind == PointerDeviceKind.mouse &&
event.buttons == kSecondaryMouseButton)) {
_calcNewPageOffset(event.delta, size.width); _calcNewPageOffset(event.delta, size.width);
} }
} }
@ -147,14 +150,14 @@ class _DrawingPageState extends State<DrawingPage> {
return Listener( return Listener(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onPointerMove: (e) => _onPointerMove(e, canvasSize), onPointerMove: (e) => _onPointerMove(e, canvasSize),
onPointerDown: (event) { onPointerDown: (d) {
Offset pos = event.localPosition; Offset pos = d.localPosition;
final scale = calcPageDependentScale(zoom, a4Page, canvasSize); final scale = calcPageDependentScale(zoom, a4Page, canvasSize);
pos = translateScreenToDocumentPoint(pos, scale, offset); pos = translateScreenToDocumentPoint(pos, scale, offset);
controller.pointDownEvent(pos, event.kind, event.tilt); controller.pointDownEvent(pos, d);
}, },
onPointerUp: (event) { onPointerUp: (e) {
controller.pointUpEvent(event.kind); controller.pointUpEvent(e);
}, },
child: GestureDetector( child: GestureDetector(
onScaleUpdate: (details) { onScaleUpdate: (details) {

View File

@ -51,6 +51,7 @@ class MyPainter extends CustomPainter {
backgroundPaint); backgroundPaint);
for (final stroke in controller.strokes) { for (final stroke in controller.strokes) {
paint.color = stroke.color;
for (int i = 0; i < stroke.points.length - 1; i++) { for (int i = 0; i < stroke.points.length - 1; i++) {
Offset pt1 = stroke.points[i].point; Offset pt1 = stroke.points[i].point;
pt1 = _translatept(pt1, size); pt1 = _translatept(pt1, size);

View File

@ -1,9 +1,9 @@
import 'dart:math'; import 'dart:math';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import '../savesystem/line_loader.dart';
import 'package:notes/savesystem/line_loader.dart';
import '../savesystem/note_file.dart'; import '../savesystem/note_file.dart';
import 'document_types.dart'; import 'document_types.dart';
import 'my_painter.dart'; import 'my_painter.dart';
@ -46,29 +46,31 @@ class PaintController extends ChangeNotifier {
return thickness; return thickness;
} }
void pointDownEvent( void pointDownEvent(Offset offset, PointerDownEvent e) async {
Offset offset, PointerDeviceKind pointer, double tilt) async { if (_allowedToDraw(e)) {
if (_allowDrawWithFinger || pointer != PointerDeviceKind.touch) {
// todo line drawn on edge where line left page // todo line drawn on edge where line left page
if (!a4Page.contains(offset)) return; if (!a4Page.contains(offset)) return;
// todo handle other pens // todo handle other pens
if (activePen != Pen.pen) return; if (activePen == Pen.eraser || activePen == Pen.selector) return;
int strokeid = strokes.isNotEmpty ? strokes.last.id + 1 : 0; int strokeid = strokes.isNotEmpty ? strokes.last.id + 1 : 0;
strokes.add(Stroke.fromPoints( strokes.add(Stroke.fromPoints(
[Point(offset, _calcTiltedWidth(3.0, tilt))], [Point(offset, _calcTiltedWidth(3.0, e.tilt))],
strokes.isNotEmpty ? strokes.last.id + 1 : 0)); strokeid,
activePen == Pen.pen
? Colors.black26
: Colors.yellow.withOpacity(.5)));
file.addStroke(strokeid); file.addStroke(strokeid);
notifyListeners(); notifyListeners();
} }
} }
void pointUpEvent(PointerDeviceKind pointer) { void pointUpEvent(PointerUpEvent e) {
if (activePen == Pen.eraser) return; if (activePen == Pen.eraser) return;
if (_allowDrawWithFinger || pointer != PointerDeviceKind.touch) { if (_allowedToDraw(e)) {
final lastStroke = strokes.last; final lastStroke = strokes.last;
if (lastStroke.points.length <= 1) { if (lastStroke.points.length <= 1) {
// if the line consists only of one point (point) add endpoint as the same to allow drawing a line // if the line consists only of one point (point) add endpoint as the same to allow drawing a line
@ -79,12 +81,20 @@ class PaintController extends ChangeNotifier {
} }
} }
void pointMoveEvent(Offset offset, PointerDeviceKind pointer, double tilt) { /// check if pointer event is allowed to draw points
bool _allowedToDraw(PointerEvent event) {
return (_allowDrawWithFinger && event.kind == PointerDeviceKind.touch) ||
event.kind == PointerDeviceKind.stylus ||
(event.kind == PointerDeviceKind.mouse &&
event.buttons == kPrimaryMouseButton);
}
void pointMoveEvent(Offset offset, PointerMoveEvent event) {
if (!a4Page.contains(offset)) { if (!a4Page.contains(offset)) {
return; return;
} }
if (_allowDrawWithFinger || pointer != PointerDeviceKind.touch) { if (_allowedToDraw(event)) {
switch (activePen) { switch (activePen) {
case Pen.eraser: case Pen.eraser:
// todo dynamic eraser size // todo dynamic eraser size
@ -105,10 +115,11 @@ class PaintController extends ChangeNotifier {
} }
break; break;
case Pen.pen: case Pen.pen:
case Pen.highlighter:
final pts = strokes.last.points; final pts = strokes.last.points;
if (pts.last.point == offset) return; if (pts.last.point == offset) return;
double newWidth = _calcTiltedWidth(5.0, tilt); double newWidth = _calcTiltedWidth(5.0, event.tilt);
if (strokes.last.points.length > 1) { if (strokes.last.points.length > 1) {
newWidth = _calcAngleDependentWidth( newWidth = _calcAngleDependentWidth(
pts.last, pts[pts.length - 2], newWidth); pts.last, pts[pts.length - 2], newWidth);
@ -118,9 +129,6 @@ class PaintController extends ChangeNotifier {
strokes.last.addPoint(p); strokes.last.addPoint(p);
file.addPoint(strokes.last.id, p); file.addPoint(strokes.last.id, p);
break; break;
case Pen.highlighter:
// TODO: Handle this case.
break;
case Pen.selector: case Pen.selector:
// TODO: Handle this case. // TODO: Handle this case.
break; break;

View File

@ -3,12 +3,14 @@ import 'package:flutter/material.dart';
import 'package:notes/collapse_drawer.dart'; import 'package:notes/collapse_drawer.dart';
import 'package:notes/all_notes_page.dart'; import 'package:notes/all_notes_page.dart';
import 'package:notes/canvas/drawing_page.dart'; import 'package:notes/canvas/drawing_page.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart';
void main() { void main() {
if (defaultTargetPlatform != TargetPlatform.android && if (defaultTargetPlatform != TargetPlatform.android &&
defaultTargetPlatform != TargetPlatform.iOS) { defaultTargetPlatform != TargetPlatform.iOS) {
sqfliteFfiInit(); sqfliteFfiInit();
databaseFactory = databaseFactoryFfi;
} }
runApp(const MyApp()); runApp(const MyApp());
} }
@ -69,9 +71,10 @@ class _MyHomePageState extends State<MyHomePage> {
case View.folders: case View.folders:
return FloatingActionButton( return FloatingActionButton(
onPressed: () { onPressed: () {
//final now = DateTime.now(); final now = DateTime.now();
//String filename = 'note-${now.year}_${now.month}_${now.day}-${now.hour}_${now.minute}.dbnote'; String filename =
String filename = 'test.dbnote'; 'note-${now.year}_${now.month}_${now.day}-${now.hour}_${now.minute}.dbnote';
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(

View File

@ -1,11 +1,32 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'canvas/drawing_page.dart';
class NoteTileData {
final String name;
final String relativePath;
final DateTime lastModified;
NoteTileData(this.name, this.relativePath, this.lastModified);
}
class NoteTile extends StatelessWidget { class NoteTile extends StatelessWidget {
const NoteTile({Key? key}) : super(key: key); const NoteTile({Key? key, required this.data}) : super(key: key);
final NoteTileData data;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DrawingPage(filePath: data.relativePath),
),
);
},
child: SizedBox(
width: 100, width: 100,
child: Column( child: Column(
children: [ children: [
@ -16,14 +37,16 @@ class NoteTile extends StatelessWidget {
color: Colors.white, color: Colors.white,
), ),
), ),
const Text( Text(
'This is a very long text mimimim lolo', data.name,
style: TextStyle(color: Colors.white), style: const TextStyle(color: Colors.white),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
const Text('11:40') Text('${data.lastModified.hour}:${data.lastModified.minute}',
style: const TextStyle(color: Colors.white))
], ],
), ),
),
); );
} }
} }

View File

@ -1,4 +1,4 @@
import 'dart:ui'; import 'package:flutter/material.dart';
import 'note_file.dart'; import 'note_file.dart';
import '../canvas/document_types.dart'; import '../canvas/document_types.dart';
@ -15,7 +15,7 @@ extension LineLoading on NoteFile {
final int csid = i['strokeid'] as int; final int csid = i['strokeid'] as int;
if (csid != strokeid) { if (csid != strokeid) {
strokeid = csid; strokeid = csid;
strokes.add(Stroke(strokeid)); strokes.add(Stroke(strokeid, Colors.green));
} }
final Point p = Point( final Point p = Point(
Offset(i['x'] as double, i['y'] as double), i['thickness'] as double); Offset(i['x'] as double, i['y'] as double), i['thickness'] as double);

View File

@ -1,29 +1,22 @@
import 'package:flutter/foundation.dart'; import 'dart:io';
import 'package:notes/savesystem/path.dart';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
class NoteFile { class NoteFile {
late Database _db; late Database _db;
String filename; String filepath;
Database db() { Database db() {
return _db; return _db;
} }
NoteFile(this.filename); NoteFile(this.filepath);
Future<void> init() async { Future<void> init() async {
String dbpath = filename; final path = (await getSavePath()).path + Platform.pathSeparator + filepath;
if (defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS) {
dbpath = '${await getDatabasesPath()}/$filename';
} else {
// Change the default factory
databaseFactory = databaseFactoryFfi;
}
_db = await openDatabase( _db = await openDatabase(
dbpath, path,
onCreate: (db, version) { onCreate: (db, version) {
return db.execute( return db.execute(
'CREATE TABLE strokes(id integer primary key autoincrement, color INTEGER, elevation INTEGER);' 'CREATE TABLE strokes(id integer primary key autoincrement, color INTEGER, elevation INTEGER);'

17
lib/savesystem/path.dart Normal file
View File

@ -0,0 +1,17 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
Future<Directory> getSavePath() async {
Directory dbpath;
if (defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS) {
dbpath = Directory(await getDatabasesPath());
} else {
dbpath = Directory(
'${(await getApplicationDocumentsDirectory()).path}${Platform.pathSeparator}notes');
}
return dbpath;
}