From 11a13049107193a8539dd0adcda3b080f7de0cbd Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Tue, 21 Feb 2023 13:54:42 +0000 Subject: [PATCH] editor: remember last-used tool Resolves #370 --- lib/components/canvas/tools/_tool.dart | 29 ++++++++++++++++++-- lib/components/canvas/tools/eraser.dart | 3 ++ lib/components/canvas/tools/highlighter.dart | 3 +- lib/components/canvas/tools/pen.dart | 11 ++++++-- lib/components/canvas/tools/select.dart | 3 ++ lib/data/prefs.dart | 12 ++++++++ lib/pages/editor/editor.dart | 28 ++++++++++++++++++- 7 files changed, 82 insertions(+), 7 deletions(-) diff --git a/lib/components/canvas/tools/_tool.dart b/lib/components/canvas/tools/_tool.dart index f46f94b71..ac4e5b56d 100644 --- a/lib/components/canvas/tools/_tool.dart +++ b/lib/components/canvas/tools/_tool.dart @@ -1,10 +1,33 @@ - import 'package:flutter/material.dart'; +import 'package:saber/data/prefs.dart'; -class Tool { +abstract class Tool { @protected @visibleForTesting const Tool(); - static const Tool textEditing = Tool(); + /// An identifier for the tool, + /// used to save the last-used tool in [Prefs.lastTool]. + ToolId get toolId; + + static const Tool textEditing = _TextEditingTool(); +} + +class _TextEditingTool extends Tool { + const _TextEditingTool(); + + @override + ToolId get toolId => ToolId.textEditing; +} + +enum ToolId { + fountainPen('fountainPen'), + ballpointPen('ballpointPen'), + highlighter('Highlighter'), + eraser('Eraser'), + select('Select'), + textEditing('TextEditingTool'); + + final String id; + const ToolId(this.id); } diff --git a/lib/components/canvas/tools/eraser.dart b/lib/components/canvas/tools/eraser.dart index 8f240d6c5..59c88f802 100644 --- a/lib/components/canvas/tools/eraser.dart +++ b/lib/components/canvas/tools/eraser.dart @@ -18,6 +18,9 @@ class Eraser extends Tool { this.size = 10 }); + @override + ToolId get toolId => ToolId.eraser; + /// Returns the indices of any [strokes] that are close to the given [eraserPos]. List checkForOverlappingStrokes(Offset eraserPos, List strokes) { final List indices = []; diff --git a/lib/components/canvas/tools/highlighter.dart b/lib/components/canvas/tools/highlighter.dart index 5587be88c..c8d078e55 100644 --- a/lib/components/canvas/tools/highlighter.dart +++ b/lib/components/canvas/tools/highlighter.dart @@ -1,6 +1,6 @@ - import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:saber/components/canvas/tools/_tool.dart'; import 'package:saber/components/canvas/tools/pen.dart'; import 'package:saber/data/prefs.dart'; import 'package:saber/i18n/strings.g.dart'; @@ -12,6 +12,7 @@ class Highlighter extends Pen { sizeMax: 100, sizeStep: 10, icon: highlighterIcon, + toolId: ToolId.highlighter, ) { strokeProperties = Prefs.lastHighlighterProperties.value; } diff --git a/lib/components/canvas/tools/pen.dart b/lib/components/canvas/tools/pen.dart index ed0204ef0..d7485d775 100644 --- a/lib/components/canvas/tools/pen.dart +++ b/lib/components/canvas/tools/pen.dart @@ -18,6 +18,7 @@ class Pen extends Tool { required this.sizeMax, required this.sizeStep, required this.icon, + required this.toolId, }); Pen.fountainPen() : @@ -26,7 +27,8 @@ class Pen extends Tool { sizeMax = 25, sizeStep = 1, icon = fountainPenIcon, - strokeProperties = Prefs.lastFountainPenProperties.value; + strokeProperties = Prefs.lastFountainPenProperties.value, + toolId = ToolId.fountainPen; Pen.ballpointPen() : name = t.editor.pens.ballpointPen, @@ -34,11 +36,16 @@ class Pen extends Tool { sizeMax = 25, sizeStep = 1, icon = ballpointPenIcon, - strokeProperties = Prefs.lastBallpointPenProperties.value; + strokeProperties = Prefs.lastBallpointPenProperties.value, + toolId = ToolId.ballpointPen; final String name; final double sizeMin, sizeMax, sizeStep; final IconData icon; + + @override + final ToolId toolId; + static const IconData fountainPenIcon = FontAwesomeIcons.penFancy; static const IconData ballpointPenIcon = FontAwesomeIcons.pen; diff --git a/lib/components/canvas/tools/select.dart b/lib/components/canvas/tools/select.dart index 763714512..5979a9527 100644 --- a/lib/components/canvas/tools/select.dart +++ b/lib/components/canvas/tools/select.dart @@ -13,6 +13,9 @@ class Select extends Tool { SelectResult selectResult = SelectResult(-1, const [], Path()); bool doneSelecting = false; + @override + ToolId get toolId => ToolId.select; + void unselect() { doneSelecting = false; selectResult.pageIndex = -1; diff --git a/lib/data/prefs.dart b/lib/data/prefs.dart index 3cd9d5a8c..95f553d42 100644 --- a/lib/data/prefs.dart +++ b/lib/data/prefs.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:nextcloud/nextcloud.dart' show NextcloudProvisioningApiUserDetails_Quota; import 'package:saber/components/canvas/_canvas_background_painter.dart'; +import 'package:saber/components/canvas/tools/_tool.dart'; import 'package:saber/components/canvas/tools/stroke_properties.dart'; import 'package:saber/data/flavor_config.dart'; import 'package:saber/data/nextcloud/nextcloud_client_extension.dart'; @@ -67,6 +68,7 @@ abstract class Prefs { static late final PlainPref> recentColorsChronological; static late final PlainPref> recentColorsPositioned; + static late final PlainPref lastTool; static late final PlainPref lastFountainPenProperties, lastBallpointPenProperties, @@ -127,6 +129,7 @@ abstract class Prefs { recentColorsChronological = PlainPref('recentColorsChronological', []); recentColorsPositioned = PlainPref('recentColorsPositioned', [], historicalKeys: ['recentColors']); + lastTool = PlainPref('lastTool', ToolId.fountainPen); lastFountainPenProperties = PlainPref('lastFountainPenProperties', StrokeProperties.fountainPen, deprecatedKeys: ['lastPenColor']); lastBallpointPenProperties = PlainPref('lastBallpointPenProperties', StrokeProperties.ballpointPen); lastHighlighterProperties = PlainPref('lastHighlighterProperties', StrokeProperties.highlighter, deprecatedKeys: ['lastHighlighterColor']); @@ -257,6 +260,7 @@ class PlainPref extends IPref { || T == typeOf>() || T == StrokeProperties || T == typeOf() || T == AxisDirection || T == ThemeMode || T == TargetPlatform + || T == ToolId ); } @@ -322,6 +326,8 @@ class PlainPref extends IPref { return await _prefs!.setInt(key, (value as ThemeMode).index); } else if (T == TargetPlatform) { return await _prefs!.setInt(key, (value as TargetPlatform).index); + } else if (T == ToolId) { + return await _prefs!.setString(key, (value as ToolId).id); } else { return await _prefs!.setString(key, value as String); } @@ -367,6 +373,12 @@ class PlainPref extends IPref { if (index == null) return null; if (index == -1) return defaultTargetPlatform as T?; return TargetPlatform.values[index] as T?; + } else if (T == ToolId) { + String id = _prefs!.getString(key)!; + return ToolId.values + .cast() + .firstWhere((toolId) => toolId?.id == id, orElse: () => null) + as T?; } else { return _prefs!.get(key) as T?; } diff --git a/lib/pages/editor/editor.dart b/lib/pages/editor/editor.dart index 5b9954ffa..7d3cd1f84 100644 --- a/lib/pages/editor/editor.dart +++ b/lib/pages/editor/editor.dart @@ -67,7 +67,33 @@ class EditorState extends State { late bool needsNaming = widget.needsNaming && Prefs.editorPromptRename.value; - Tool currentTool = Pen.currentPen; + late Tool _currentTool = () { + switch (Prefs.lastTool.value) { + case ToolId.fountainPen: + if (Pen.currentPen.toolId != Prefs.lastTool.value) { + Pen.currentPen = Pen.fountainPen(); + } + return Pen.currentPen; + case ToolId.ballpointPen: + if (Pen.currentPen.toolId != Prefs.lastTool.value) { + Pen.currentPen = Pen.ballpointPen(); + } + return Pen.currentPen; + case ToolId.highlighter: + return Highlighter.currentHighlighter; + case ToolId.eraser: + return Eraser(); + case ToolId.select: + return Select.currentSelect; + case ToolId.textEditing: + return Tool.textEditing; + } + }(); + Tool get currentTool => _currentTool; + set currentTool(Tool tool) { + _currentTool = tool; + Prefs.lastTool.value = tool.toolId; + } /// Whether the note has changed since it was last saved bool _hasEdited = false;