Cleaned up preview app

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-09-02 00:30:05 +02:00
parent 91c70fc4af
commit 2caad7ad5a
+36 -47
View File
@@ -1,9 +1,9 @@
import "dart:async";
import "dart:io";
import "dart:typed_data";
import "package:custom_cursor/custom_cursor.dart";
import "package:desktop_drop/desktop_drop.dart";
import "package:flutter/foundation.dart";
import "package:flutter/material.dart";
import "package:flutter/services.dart" show rootBundle;
@@ -41,7 +41,6 @@ class CursorGridScreen extends StatefulWidget {
class _CursorGridScreenState extends State<CursorGridScreen> {
static const _defaultAssets = <String>["normal", "move", "resize"];
static const _sizePresets = <int>[24, 30, 32, 36, 48, 64, 128];
Map<String, CursorAsset> _cursors = {};
final Map<String, Uint8List> _rawFiles = {};
@@ -53,7 +52,6 @@ class _CursorGridScreenState extends State<CursorGridScreen> {
bool _respectOsScale = true;
bool _rtl = false;
double _systemScale = 1.0;
String _customSize = "";
DecodeOptions get _options {
return DecodeOptions(
@@ -174,21 +172,13 @@ class _CursorGridScreenState extends State<CursorGridScreen> {
setState(() {
_cursors = {};
_loading = true;
_targetSize = 32;
});
await _loadDefaults();
}
void _setPreset(int? size) {
_targetSize = size?.toDouble();
if (size != null) _customSize = "";
unawaited(_redecode());
}
void _applyCustomSize(String text) {
final parsed = double.tryParse(text);
if (parsed != null && parsed > 0) {
_targetSize = parsed;
}
unawaited(_redecode());
}
@@ -219,13 +209,11 @@ class _CursorGridScreenState extends State<CursorGridScreen> {
children: [
_ScaleControls(
preset: _targetSize,
customSize: _customSize,
respectOsScale: _respectOsScale,
osScale: _systemScale,
rtl: _rtl,
onPreset: (size) => setState(() => _setPreset(size)),
onCustomChanged: (text) => setState(() => _customSize = text),
onCustomSubmitted: _applyCustomSize,
onToggleOsScale: (value) =>
setState(() => _toggleOsScale(value)),
onToggleRtl: (value) => setState(() => _rtl = value),
@@ -262,25 +250,19 @@ class _CursorGridScreenState extends State<CursorGridScreen> {
class _ScaleControls extends StatelessWidget {
const _ScaleControls({
required this.preset,
required this.customSize,
required this.respectOsScale,
required this.osScale,
required this.rtl,
required this.onPreset,
required this.onCustomChanged,
required this.onCustomSubmitted,
required this.onToggleOsScale,
required this.onToggleRtl,
});
final double? preset;
final String customSize;
final bool respectOsScale;
final double osScale;
final bool rtl;
final ValueChanged<int?> onPreset;
final ValueChanged<String> onCustomChanged;
final ValueChanged<String> onCustomSubmitted;
final ValueChanged<bool> onToggleOsScale;
final ValueChanged<bool> onToggleRtl;
@@ -294,24 +276,19 @@ class _ScaleControls extends StatelessWidget {
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Text("Size:", style: Theme.of(context).textTheme.titleSmall),
for (final size in _CursorGridScreenState._sizePresets)
ChoiceChip(
label: Text("$size"),
selected: preset == size,
onSelected: (_) => onPreset(size),
),
SizedBox(
width: 72,
child: TextField(
decoration: const InputDecoration(
labelText: "Custom",
isDense: true,
),
keyboardType: TextInputType.number,
onChanged: onCustomChanged,
onSubmitted: onCustomSubmitted,
),
Slider.adaptive(
min: 16,
max: 128,
value: preset ?? 32,
divisions: 8,
showValueIndicator: ShowValueIndicator.alwaysVisible,
onChanged: (value) {
onPreset(value.toInt());
},
),
Row(
spacing: 8,
children: [
Directionality(
textDirection: TextDirection.ltr,
child: Row(
@@ -333,7 +310,8 @@ class _ScaleControls extends StatelessWidget {
],
),
),
SwitchListTile(
Expanded(
child: SwitchListTile.adaptive(
contentPadding: EdgeInsets.zero,
title: Text(
"Respect OS pointer size (${osScale.toStringAsFixed(2)}x)",
@@ -341,6 +319,9 @@ class _ScaleControls extends StatelessWidget {
value: respectOsScale,
onChanged: onToggleOsScale,
),
),
],
),
],
),
);
@@ -361,12 +342,16 @@ class _DropRegion extends StatelessWidget {
final ValueChanged<DropEventDetails> onDragExited;
final ValueChanged<DropDoneDetails> onDragDone;
bool get useDropTarget =>
kIsWeb || Platform.isWindows || Platform.isLinux || Platform.isMacOS;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
child: DropTarget(
enable: useDropTarget,
onDragEntered: onDragEntered,
onDragExited: onDragExited,
onDragDone: onDragDone,
@@ -387,9 +372,11 @@ class _DropRegion extends StatelessWidget {
),
),
child: Text(
dragging
useDropTarget
? dragging
? "Release to load cursors"
: "Drop cursor/image files here (cur, ani, PNG, GIF, SVG...)",
: "Drop cursor/image files here (cur, ani, PNG, GIF, SVG...)"
: "Tap to load cursor/image files (cur, ani, PNG, GIF, SVG...)",
style: theme.textTheme.titleMedium,
textAlign: TextAlign.center,
),
@@ -467,10 +454,10 @@ class _CursorCardState extends State<CursorCard> {
),
),
child: Column(
spacing: 12,
mainAxisAlignment: MainAxisAlignment.center,
children: [
AssetPreview(asset: widget.asset),
const SizedBox(height: 12),
Flexible(child: AssetPreview(asset: widget.asset)),
Text(widget.name, style: theme.textTheme.titleMedium),
],
),
@@ -558,12 +545,14 @@ class _CursorPreview extends StatelessWidget {
final rtl = effectiveDirection(context) == TextDirection.rtl;
final width = cursor.image.width.toDouble();
final height = cursor.image.height.toDouble();
return SizedBox(
width: width,
height: height,
return Center(
child: Transform.scale(
scaleX: rtl ? -1 : 1,
child: RawImage(image: cursor.image, width: width, height: height),
child: RawImage(
image: cursor.image,
width: width,
height: height,
),
),
);
}