load on all notes page all available .dbnote files and display them
reopen file on tile click
This commit is contained in:
parent
8ea4dc281e
commit
7baef13eae
@ -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;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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(
|
||||||
|
@ -1,28 +1,51 @@
|
|||||||
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(
|
||||||
width: 100,
|
onTap: () {
|
||||||
child: Column(
|
Navigator.push(
|
||||||
children: [
|
context,
|
||||||
SizedBox(
|
MaterialPageRoute(
|
||||||
height: 150,
|
builder: (context) => DrawingPage(filePath: data.relativePath),
|
||||||
width: 100,
|
),
|
||||||
child: Container(
|
);
|
||||||
color: Colors.white,
|
},
|
||||||
|
child: SizedBox(
|
||||||
|
width: 100,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 150,
|
||||||
|
width: 100,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
const Text(
|
data.name,
|
||||||
'This is a very long text mimimim lolo',
|
style: const TextStyle(color: Colors.white),
|
||||||
style: TextStyle(color: Colors.white),
|
overflow: TextOverflow.ellipsis,
|
||||||
overflow: TextOverflow.ellipsis,
|
),
|
||||||
),
|
Text('${data.lastModified.hour}:${data.lastModified.minute}',
|
||||||
const Text('11:40')
|
style: const TextStyle(color: Colors.white))
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
17
lib/savesystem/path.dart
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user