Files
clide/lib/widgets/src/clide_icon.dart
T
jpmschweitzerandClaude Opus 4.8 18cd945380 refactor(theme): route consumer reads through ClideSettings.theme (T-473)
Migrate ClideTheme.of(context) reads across the widget, feature, and shell
layers to the unified ClideSettings.theme.of(context) facade (D-101), so
theme/i18n/fonts/settings share one widget-facing entry. The facade delegates
straight to ClideTheme, so behaviour is unchanged — goldens are unmoved.

The low-level theme provider keeps its direct ClideTheme.of: the facade is
built on it, and the two kernel sites (ClideTheme's own definition + the
panels drag-resize widget) stay direct to avoid a widgets→kernel import cycle.
Dead controller.dart/kernel.dart imports left by the sweep removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 21:47:15 +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/widgets/src/clide_settings.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 ?? ClideSettings.theme.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;
}