Skip to content

Commit 33a500d

Browse files
committed
fix: pen size picker in vertical toolbar
1 parent 4b46d70 commit 33a500d

File tree

4 files changed

+100
-17
lines changed

4 files changed

+100
-17
lines changed

lib/components/theming/row_col.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import 'package:flutter/material.dart';
2+
3+
class RowCol extends StatelessWidget {
4+
const RowCol({
5+
super.key,
6+
required this.axis,
7+
this.mainAxisSize = MainAxisSize.max,
8+
this.mainAxisAlignment = MainAxisAlignment.start,
9+
required this.children,
10+
});
11+
12+
final Axis axis;
13+
final MainAxisSize mainAxisSize;
14+
final MainAxisAlignment mainAxisAlignment;
15+
final List<Widget> children;
16+
17+
@override
18+
Widget build(BuildContext context) {
19+
return axis == Axis.horizontal
20+
? Row(
21+
mainAxisSize: mainAxisSize,
22+
mainAxisAlignment: mainAxisAlignment,
23+
children: children,
24+
)
25+
: Column(
26+
mainAxisSize: mainAxisSize,
27+
mainAxisAlignment: mainAxisAlignment,
28+
children: children,
29+
);
30+
}
31+
}

lib/components/toolbar/pen_modal.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_svg/flutter_svg.dart';
33
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
4+
import 'package:saber/components/theming/row_col.dart';
45
import 'package:saber/components/toolbar/size_picker.dart';
6+
import 'package:saber/data/extensions/axis_extensions.dart';
7+
import 'package:saber/data/prefs.dart';
58
import 'package:saber/data/tools/_tool.dart';
69
import 'package:saber/data/tools/highlighter.dart';
710
import 'package:saber/data/tools/pen.dart';
@@ -26,6 +29,7 @@ class PenModal extends StatefulWidget {
2629
class _PenModalState extends State<PenModal> {
2730
@override
2831
Widget build(BuildContext context) {
32+
final axis = Prefs.editorToolbarAlignment.value.axis.opposite;
2933
final Tool currentTool = widget.getTool();
3034
final Pen currentPen;
3135
if (currentTool is Pen) {
@@ -34,14 +38,16 @@ class _PenModalState extends State<PenModal> {
3438
return const SizedBox();
3539
}
3640

37-
return Row(
41+
return RowCol(
42+
axis: axis,
3843
mainAxisAlignment: MainAxisAlignment.center,
3944
children: [
4045
SizePicker(
46+
axis: axis,
4147
pen: currentPen,
4248
),
4349
if (currentPen is! Highlighter && currentPen is! Pencil) ...[
44-
const SizedBox(width: 8),
50+
const SizedBox.square(dimension: 8),
4551
IconButton(
4652
onPressed: () => setState(() {
4753
widget.setTool(Pen.fountainPen());
@@ -67,6 +73,7 @@ class _PenModalState extends State<PenModal> {
6773
),
6874
),
6975
),
76+
const SizedBox.square(dimension: 8),
7077
IconButton(
7178
onPressed: () => setState(() {
7279
widget.setTool(Pen.ballpointPen());
@@ -92,6 +99,7 @@ class _PenModalState extends State<PenModal> {
9299
),
93100
),
94101
),
102+
const SizedBox.square(dimension: 8),
95103
IconButton(
96104
onPressed: () => setState(() {
97105
widget.setTool(ShapePen());

lib/components/toolbar/size_picker.dart

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import 'package:flutter/foundation.dart';
22
import 'package:flutter/material.dart';
3+
import 'package:saber/components/theming/row_col.dart';
34
import 'package:saber/data/tools/pen.dart';
45
import 'package:saber/i18n/strings.g.dart';
56

67
class SizePicker extends StatefulWidget {
78
const SizePicker({
89
super.key,
10+
required this.axis,
911
required this.pen,
1012
});
1113

14+
final Axis axis;
1215
final Pen pen;
1316

1417
@override
@@ -28,7 +31,8 @@ class _SizePickerState extends State<SizePicker> {
2831
@override
2932
Widget build(BuildContext context) {
3033
final colorScheme = Theme.of(context).colorScheme;
31-
return Row(
34+
return RowCol(
35+
axis: widget.axis,
3236
mainAxisSize: MainAxisSize.min,
3337
children: [
3438
Column(
@@ -49,6 +53,7 @@ class _SizePickerState extends State<SizePicker> {
4953
padding: const EdgeInsets.symmetric(vertical: 8),
5054
child: _SizeSlider(
5155
pen: widget.pen,
56+
axis: widget.axis,
5257
setState: setState,
5358
),
5459
),
@@ -62,17 +67,24 @@ class _SizeSlider extends StatelessWidget {
6267
// ignore: unused_element
6368
super.key,
6469
required this.pen,
70+
required this.axis,
6571
required this.setState,
6672
});
6773

6874
final Pen pen;
75+
final Axis axis;
6976
final void Function(void Function()) setState;
7077

71-
static const Size _size = Size(150, 25);
78+
static const double _smallLength = 25;
79+
static const double _largeLength = 150;
7280

73-
void onDrag(double localDx) {
74-
final relX = clampDouble(localDx / _size.width, 0, 1);
75-
final stepsFromMin = (relX * pen.sizeStepsBetweenMinAndMax).round();
81+
/// [percent] is a value between 0 and 1
82+
/// where 0 is the start of the slider and 1 is the end.
83+
///
84+
/// Values outside of this range are allowed but will be clamped.
85+
void onDrag(double percent) {
86+
percent = clampDouble(percent, 0, 1);
87+
final stepsFromMin = (percent * pen.sizeStepsBetweenMinAndMax).round();
7688
final newSize = pen.sizeMin + stepsFromMin * pen.sizeStep;
7789
if (newSize == pen.options.size) return;
7890
setState(() {
@@ -84,16 +96,30 @@ class _SizeSlider extends StatelessWidget {
8496
Widget build(BuildContext context) {
8597
final colorScheme = Theme.of(context).colorScheme;
8698
return GestureDetector(
87-
onHorizontalDragStart: (details) => onDrag(details.localPosition.dx),
88-
onHorizontalDragUpdate: (details) => onDrag(details.localPosition.dx),
89-
child: CustomPaint(
90-
size: _size,
91-
painter: _SizeSliderPainter(
92-
minSize: pen.sizeMin,
93-
maxSize: pen.sizeMax,
94-
currentSize: pen.options.size,
95-
trackColor: colorScheme.onBackground.withOpacity(0.2),
96-
thumbColor: colorScheme.primary,
99+
onHorizontalDragStart: axis == Axis.horizontal
100+
? (details) => onDrag(details.localPosition.dx / _largeLength)
101+
: null,
102+
onHorizontalDragUpdate: axis == Axis.horizontal
103+
? (details) => onDrag(details.localPosition.dx / _largeLength)
104+
: null,
105+
onVerticalDragStart: axis == Axis.vertical
106+
? (details) => onDrag(details.localPosition.dy / _largeLength)
107+
: null,
108+
onVerticalDragUpdate: axis == Axis.vertical
109+
? (details) => onDrag(details.localPosition.dy / _largeLength)
110+
: null,
111+
child: RotatedBox(
112+
quarterTurns: axis == Axis.horizontal ? 0 : 1,
113+
child: CustomPaint(
114+
size: const Size(_largeLength, _smallLength),
115+
painter: _SizeSliderPainter(
116+
axis: axis,
117+
minSize: pen.sizeMin,
118+
maxSize: pen.sizeMax,
119+
currentSize: pen.options.size,
120+
trackColor: colorScheme.onBackground.withOpacity(0.2),
121+
thumbColor: colorScheme.primary,
122+
),
97123
),
98124
),
99125
);
@@ -102,13 +128,15 @@ class _SizeSlider extends StatelessWidget {
102128

103129
class _SizeSliderPainter extends CustomPainter {
104130
_SizeSliderPainter({
131+
required this.axis,
105132
required this.minSize,
106133
required this.maxSize,
107134
required this.currentSize,
108135
required this.trackColor,
109136
required this.thumbColor,
110137
});
111138

139+
final Axis axis;
112140
final double minSize;
113141
final double maxSize;
114142
final double currentSize;
@@ -158,6 +186,7 @@ class _SizeSliderPainter extends CustomPainter {
158186
@override
159187
bool shouldRepaint(covariant CustomPainter oldDelegate) {
160188
return oldDelegate is! _SizeSliderPainter ||
189+
oldDelegate.axis != axis ||
161190
oldDelegate.minSize != minSize ||
162191
oldDelegate.maxSize != maxSize ||
163192
oldDelegate.currentSize != currentSize ||
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'package:flutter/material.dart';
2+
3+
extension AxisExtensions on Axis {
4+
Axis get opposite => switch (this) {
5+
Axis.horizontal => Axis.vertical,
6+
Axis.vertical => Axis.horizontal,
7+
};
8+
}
9+
10+
extension AxisDirectionExtensions on AxisDirection {
11+
Axis get axis => switch (this) {
12+
AxisDirection.up || AxisDirection.down => Axis.vertical,
13+
AxisDirection.left || AxisDirection.right => Axis.horizontal,
14+
};
15+
}

0 commit comments

Comments
 (0)