From 887cfa981002eafc36240889f6ee6a0c5bb25426 Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Wed, 1 Jan 2025 18:33:47 +0100 Subject: [PATCH] Add offset to grid, add docs pages --- api/lib/src/models/tool.dart | 2 ++ api/lib/src/models/tool.freezed.dart | 30 ++++++++++++++++++-- api/lib/src/models/tool.g.dart | 4 +++ app/lib/handlers/grid.dart | 15 ++++++---- app/lib/l10n/app_en.arb | 3 +- app/lib/selections/properties/pen.dart | 1 + app/lib/selections/tools/grid.dart | 11 +++++++ docs/astro.config.mjs | 12 ++++++++ docs/pnpm-lock.yaml | 8 +++--- docs/src/content/docs/docs/v2/tools/grid.md | 21 ++++++++++++++ docs/src/content/docs/docs/v2/tools/ruler.md | 20 +++++++++++++ docs/src/content/docs/docs/v2/utilities.md | 10 +++++++ docs/src/translations/en.json | 5 +++- metadata/en-US/changelogs/127.txt | 2 ++ 14 files changed, 129 insertions(+), 15 deletions(-) create mode 100644 docs/src/content/docs/docs/v2/tools/grid.md create mode 100644 docs/src/content/docs/docs/v2/tools/ruler.md diff --git a/api/lib/src/models/tool.dart b/api/lib/src/models/tool.dart index c6116175fb82..8fdcbf56ec44 100644 --- a/api/lib/src/models/tool.dart +++ b/api/lib/src/models/tool.dart @@ -205,6 +205,8 @@ sealed class Tool with _$Tool { @Default(SRGBColor.black) @ColorJsonConverter() SRGBColor color, @Default(20) double xSize, @Default(20) double ySize, + @Default(0) double xOffset, + @Default(0) double yOffset, }) = GridTool; factory Tool.eyeDropper({ diff --git a/api/lib/src/models/tool.freezed.dart b/api/lib/src/models/tool.freezed.dart index e34fc9f55cea..7c5c3fbc05d9 100644 --- a/api/lib/src/models/tool.freezed.dart +++ b/api/lib/src/models/tool.freezed.dart @@ -2933,7 +2933,9 @@ abstract class _$$GridToolImplCopyWith<$Res> implements $ToolCopyWith<$Res> { String displayIcon, @ColorJsonConverter() SRGBColor color, double xSize, - double ySize}); + double ySize, + double xOffset, + double yOffset}); } /// @nodoc @@ -2954,6 +2956,8 @@ class __$$GridToolImplCopyWithImpl<$Res> Object? color = null, Object? xSize = null, Object? ySize = null, + Object? xOffset = null, + Object? yOffset = null, }) { return _then(_$GridToolImpl( name: null == name @@ -2976,6 +2980,14 @@ class __$$GridToolImplCopyWithImpl<$Res> ? _value.ySize : ySize // ignore: cast_nullable_to_non_nullable as double, + xOffset: null == xOffset + ? _value.xOffset + : xOffset // ignore: cast_nullable_to_non_nullable + as double, + yOffset: null == yOffset + ? _value.yOffset + : yOffset // ignore: cast_nullable_to_non_nullable + as double, )); } } @@ -2989,6 +3001,8 @@ class _$GridToolImpl extends GridTool { @ColorJsonConverter() this.color = SRGBColor.black, this.xSize = 20, this.ySize = 20, + this.xOffset = 0, + this.yOffset = 0, final String? $type}) : $type = $type ?? 'grid', super._(); @@ -3012,13 +3026,19 @@ class _$GridToolImpl extends GridTool { @override @JsonKey() final double ySize; + @override + @JsonKey() + final double xOffset; + @override + @JsonKey() + final double yOffset; @JsonKey(name: 'type') final String $type; @override String toString() { - return 'Tool.grid(name: $name, displayIcon: $displayIcon, color: $color, xSize: $xSize, ySize: $ySize)'; + return 'Tool.grid(name: $name, displayIcon: $displayIcon, color: $color, xSize: $xSize, ySize: $ySize, xOffset: $xOffset, yOffset: $yOffset)'; } /// Create a copy of Tool @@ -3043,7 +3063,9 @@ abstract class GridTool extends Tool { final String displayIcon, @ColorJsonConverter() final SRGBColor color, final double xSize, - final double ySize}) = _$GridToolImpl; + final double ySize, + final double xOffset, + final double yOffset}) = _$GridToolImpl; GridTool._() : super._(); factory GridTool.fromJson(Map json) = @@ -3057,6 +3079,8 @@ abstract class GridTool extends Tool { SRGBColor get color; double get xSize; double get ySize; + double get xOffset; + double get yOffset; /// Create a copy of Tool /// with the given fields replaced by the non-null parameter values. diff --git a/api/lib/src/models/tool.g.dart b/api/lib/src/models/tool.g.dart index d53ab1358406..7c70f6a9ba45 100644 --- a/api/lib/src/models/tool.g.dart +++ b/api/lib/src/models/tool.g.dart @@ -464,6 +464,8 @@ _$GridToolImpl _$$GridToolImplFromJson(Map json) => _$GridToolImpl( : const ColorJsonConverter().fromJson((json['color'] as num).toInt()), xSize: (json['xSize'] as num?)?.toDouble() ?? 20, ySize: (json['ySize'] as num?)?.toDouble() ?? 20, + xOffset: (json['xOffset'] as num?)?.toDouble() ?? 0, + yOffset: (json['yOffset'] as num?)?.toDouble() ?? 0, $type: json['type'] as String?, ); @@ -474,6 +476,8 @@ Map _$$GridToolImplToJson(_$GridToolImpl instance) => 'color': const ColorJsonConverter().toJson(instance.color), 'xSize': instance.xSize, 'ySize': instance.ySize, + 'xOffset': instance.xOffset, + 'yOffset': instance.yOffset, 'type': instance.$type, }; diff --git a/app/lib/handlers/grid.dart b/app/lib/handlers/grid.dart index e0a4e5b028eb..f72ee690f18a 100644 --- a/app/lib/handlers/grid.dart +++ b/app/lib/handlers/grid.dart @@ -16,10 +16,13 @@ class GridHandler extends Handler with PointerManipulationHandler { @override Offset getPointerPosition(Offset position, Size viewportSize) { - return Offset( - (position.dx / data.xSize).round() * data.xSize, - (position.dy / data.ySize).round() * data.ySize, - ); + final xSize = data.xSize; + final ySize = data.ySize; + final xOffset = data.xOffset; + final yOffset = data.yOffset; + final x = (position.dx - xOffset) / xSize; + final y = (position.dy - yOffset) / ySize; + return Offset(x.round() * xSize + xOffset, y.round() * ySize + yOffset); } } @@ -31,7 +34,7 @@ class GridRenderer extends Renderer { DocumentInfo info, CameraTransform transform, [ColorScheme? colorScheme, bool foreground = false]) { if (element.xSize > 0) { - double x = 0; + double x = -element.xSize + element.xOffset % element.xSize; while (x < size.width) { final localX = x / transform.size; canvas.drawLine( @@ -46,7 +49,7 @@ class GridRenderer extends Renderer { } } if (element.ySize > 0) { - double y = 0; + double y = -element.ySize + element.yOffset % element.ySize; while (y < size.height) { final localY = y / transform.size; canvas.drawLine( diff --git a/app/lib/l10n/app_en.arb b/app/lib/l10n/app_en.arb index 3c4397a1db5d..a090d230dd0a 100644 --- a/app/lib/l10n/app_en.arb +++ b/app/lib/l10n/app_en.arb @@ -636,5 +636,6 @@ "confirmPassword": "Confirm password", "passwordMismatch": "The passwords do not match", "action": "Action", - "svgText": "SVG Text" + "svgText": "SVG Text", + "offset": "Offset" } diff --git a/app/lib/selections/properties/pen.dart b/app/lib/selections/properties/pen.dart index f6d46422092f..7b5a588b1a8f 100644 --- a/app/lib/selections/properties/pen.dart +++ b/app/lib/selections/properties/pen.dart @@ -19,6 +19,7 @@ class PenPropertySelection extends PropertySelection property.copyWith(color: value.withValues(a: property.color.a))), title: Text(LeapLocalizations.of(context).color), ), + const SizedBox(height: 4), ExactSlider( value: property.color.a.toDouble(), header: Text(AppLocalizations.of(context).alpha), diff --git a/app/lib/selections/tools/grid.dart b/app/lib/selections/tools/grid.dart index c393b3957594..d8e680cbdc01 100644 --- a/app/lib/selections/tools/grid.dart +++ b/app/lib/selections/tools/grid.dart @@ -19,6 +19,17 @@ class GridToolSelection extends ToolSelection { ), ), const SizedBox(height: 8), + OffsetPropertyView( + title: Text(AppLocalizations.of(context).offset), + value: Offset(selected.first.xOffset, selected.first.yOffset), + onChanged: (value) => update( + context, + selected + .map((e) => e.copyWith(xOffset: value.dx, yOffset: value.dy)) + .toList(), + ), + ), + const SizedBox(height: 8), ColorField( value: selected.first.color, onChanged: (value) => update( diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 1ef5855f326e..06825ad52cf8 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -86,6 +86,10 @@ export default defineConfig({ ...getSidebarTranslatedLabel("Add"), link: "/docs/v2/add/", }, + { + ...getSidebarTranslatedLabel("Utilities"), + link: "/docs/v2/utilities/", + }, { ...getSidebarTranslatedLabel("Collaboration"), link: "/docs/v2/collaboration/", @@ -169,6 +173,14 @@ export default defineConfig({ ...getSidebarTranslatedLabel("Presentation"), link: "/docs/v2/tools/presentation/", }, + { + ...getSidebarTranslatedLabel("Ruler"), + link: "/docs/v2/tools/ruler/", + }, + { + ...getSidebarTranslatedLabel("Grid"), + link: "/docs/v2/tools/grid/", + }, ], }, ], diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 312221fdb813..c02a46adede8 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -1884,8 +1884,8 @@ packages: resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==} engines: {node: '>=18'} - p-timeout@6.1.3: - resolution: {integrity: sha512-UJUyfKbwvr/uZSV6btANfb+0t/mOhKV/KXcCUTp8FcQI+v/0d+wXqH4htrW0E4rR6WiEO/EPvUFiV9D5OI4vlw==} + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} p-try@2.2.0: @@ -4901,9 +4901,9 @@ snapshots: p-queue@8.0.1: dependencies: eventemitter3: 5.0.1 - p-timeout: 6.1.3 + p-timeout: 6.1.4 - p-timeout@6.1.3: {} + p-timeout@6.1.4: {} p-try@2.2.0: {} diff --git a/docs/src/content/docs/docs/v2/tools/grid.md b/docs/src/content/docs/docs/v2/tools/grid.md new file mode 100644 index 000000000000..7a130f3bfe07 --- /dev/null +++ b/docs/src/content/docs/docs/v2/tools/grid.md @@ -0,0 +1,21 @@ +--- +title: Grid tool +--- + +:::note[🔘 Toggleable tool] + +This is a special tool. +You can't select it and it gets toggled if you click on it. + +::: + +With this tool you can show a grid over the canvas. +Inputs get snapped to the grid. + +## Configuration + +| Property | Default | Description | +| -------: | :------: | :--------------------- | +| Size | (20, 20) | The size of grid cells | +| Offset | (0, 0) | The offset of the grid | +| Color | Black | The color of the grid | diff --git a/docs/src/content/docs/docs/v2/tools/ruler.md b/docs/src/content/docs/docs/v2/tools/ruler.md new file mode 100644 index 000000000000..445b7caee062 --- /dev/null +++ b/docs/src/content/docs/docs/v2/tools/ruler.md @@ -0,0 +1,20 @@ +--- +title: Ruler tool +--- + +:::note[🔘 Toggleable tool] + +This is a special tool. +You can't select it and it gets toggled if you click on it. + +::: + +With this tool you can show a ruler over the canvas. +Inputs get snapped to the ruler. + +## Configuration + +| Property | Default | Description | +| -------: | :-------: | :----------------------------------------------------------- | +| Size | 100 | The size of the ruler | +| Color | *Not set* | The color of the ruler. If not set, it uses the theme color. | diff --git a/docs/src/content/docs/docs/v2/utilities.md b/docs/src/content/docs/docs/v2/utilities.md index 9ff3df1823b6..ea28d33b3e44 100644 --- a/docs/src/content/docs/docs/v2/utilities.md +++ b/docs/src/content/docs/docs/v2/utilities.md @@ -15,6 +15,16 @@ Here are all page specific properties. Currently you can find the background set ## View +:::note + +This tab was removed in the nightly release. +Please visit the tools for more information: + +- [Grid](/docs/v2/tools/grid) +- [Ruler](/docs/v2/tools/ruler) + +::: + ### Grid The grid allows you to exactly position elements. You can use it to move elements or create shapes. diff --git a/docs/src/translations/en.json b/docs/src/translations/en.json index 1081b76095dd..113324cbdf91 100644 --- a/docs/src/translations/en.json +++ b/docs/src/translations/en.json @@ -44,5 +44,8 @@ "faq": "FAQ", "versions": "Versions", "nightly": "Nightly", - "privacy_policy": "Privacy policy" + "privacy_policy": "Privacy policy", + "ruler": "Ruler", + "grid": "Grid", + "utilities": "Utilities" } diff --git a/metadata/en-US/changelogs/127.txt b/metadata/en-US/changelogs/127.txt index 3f5716b30dd9..20999fa7ee2d 100644 --- a/metadata/en-US/changelogs/127.txt +++ b/metadata/en-US/changelogs/127.txt @@ -5,7 +5,9 @@ * Add toggleable tools * Move ruler into own tool * Add color property + * Add size property * Move grid into own tool + * Add offset property * Add password protected notes ([#771](https://github.com/LinwoodDev/Butterfly/issues/771)) * Add option to import svg as text ([#596](https://github.com/LinwoodDev/Butterfly/issues/596)) * Fix undo/redo tools not showing status correctly