Files
clide/lib/widgets/src/clide_icon.dart
T
jpmschweitzerandClaude Opus 4.8 6d0ebab721 chore: adopt Dart 3.9 toolchain — honest floor + tall-style reformat (T-353)
Raise the declared minimums in pubspec.yaml to what our deps already
require: Flutter >=3.35.0 / Dart >=3.9.0 (was 3.19.0 / 3.5.0). alchemist
0.12 needs Flutter 3.32; Dart 3.9 first ships in Flutter 3.35, so 3.35 is
the binding floor. Pin the exact build toolchain in .fvmrc (Flutter
3.44.1).

Moving to the Dart 3.9 language level switches `dart format` to the new
"tall" style and enables two new lints. This commit is the resulting
mechanical churn, isolated from any behaviour change:
  - whole-tree `dart format` reformat (tall style)
  - `dart fix` for unnecessary_underscores + use_null_aware_elements

No runtime behaviour change; `make test` green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 12:11:53 +02:00

69 lines
2.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:clide/kernel/src/theme/controller.dart';
import 'package:flutter/widgets.dart';
/// Stateless painter producing a single-color icon. Every icon in
/// `widgets/src/icons/` subclasses this; widgets wrap with [ClideIcon]
/// for size + color-from-theme.
abstract class ClideIconPainter {
const ClideIconPainter();
/// Paint the icon into a unit square (0,0 .. 1,1).
void paint(Canvas canvas, Color color);
}
/// Draws nothing, but [ClideIcon] still reserves its `size×size` box — so a
/// caller can keep the icon slot for alignment without showing a glyph. This is
/// the *intentional* empty (e.g. a non-search filter field), distinct from an
/// unknown glyph name, which renders a visible `placeholder` error box (T-314).
class EmptyIconPainter extends ClideIconPainter {
const EmptyIconPainter();
@override
void paint(Canvas canvas, Color color) {}
@override
bool operator ==(Object other) => other is EmptyIconPainter;
@override
int get hashCode => (EmptyIconPainter).hashCode;
}
class ClideIcon extends StatelessWidget {
const ClideIcon(this.painter, {super.key, this.size = 14, this.color});
final ClideIconPainter painter;
final double size;
final Color? color;
@override
Widget build(BuildContext context) {
final resolved = color ?? ClideTheme.of(context).surface.globalForeground;
return SizedBox(
width: size,
height: size,
child: CustomPaint(
size: Size(size, size),
painter: _IconPainterAdapter(painter: painter, color: resolved),
),
);
}
}
class _IconPainterAdapter extends CustomPainter {
_IconPainterAdapter({required this.painter, required this.color});
final ClideIconPainter painter;
final Color color;
@override
void paint(Canvas canvas, Size size) {
canvas.save();
canvas.scale(size.width, size.height);
painter.paint(canvas, color);
canvas.restore();
}
@override
bool shouldRepaint(covariant _IconPainterAdapter old) => old.painter != painter || old.color != color;
}