87 lines
2.7 KiB
Dart
87 lines
2.7 KiB
Dart
// packages/feature_game_sudoku/lib/widgets/number_pad.dart
|
|
import 'package:flutter/material.dart';
|
|
import 'package:service_api/service_api.dart'; // 👈 SudokuTheme import
|
|
|
|
class NumberPad extends StatelessWidget {
|
|
final int blockSize;
|
|
final SudokuTheme theme;
|
|
final Map<int, int> numberCounts;
|
|
final int? selectedNumber;
|
|
final Function(int) onNumberTapped;
|
|
final bool isLandscape;
|
|
|
|
const NumberPad({
|
|
super.key,
|
|
required this.blockSize,
|
|
required this.theme,
|
|
required this.numberCounts,
|
|
required this.selectedNumber,
|
|
required this.onNumberTapped,
|
|
required this.isLandscape,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final int gridSize = blockSize * blockSize;
|
|
final ThemeData themeData = Theme.of(context);
|
|
final bool isDark = themeData.brightness == Brightness.dark;
|
|
|
|
final Color selectedColor = themeData.primaryColor;
|
|
final Color onSelectedColor = themeData.colorScheme.onPrimary;
|
|
|
|
final Color completedColor = isDark ? Colors.white24 : Colors.black26;
|
|
final Color completedTextColor = isDark ? Colors.white54 : Colors.black54;
|
|
|
|
final Color defaultTextColor = isDark ? Colors.white70 : Colors.black87;
|
|
|
|
List<Widget> numberButtons = List.generate(gridSize, (index) {
|
|
int numberValue = index + 1;
|
|
String numberSymbol = theme.getSymbol(numberValue);
|
|
bool isSelected = (numberValue == selectedNumber);
|
|
bool isCompleted = (numberCounts[numberValue] ?? 0) >= gridSize;
|
|
|
|
Widget button = ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: isSelected ? selectedColor : null,
|
|
foregroundColor: isSelected ? onSelectedColor : defaultTextColor,
|
|
disabledBackgroundColor: completedColor,
|
|
disabledForegroundColor: completedTextColor,
|
|
padding: const EdgeInsets.all(4.0),
|
|
textStyle: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4))
|
|
),
|
|
onPressed: isCompleted
|
|
? null
|
|
: () => onNumberTapped(numberValue),
|
|
child: FittedBox(
|
|
fit: BoxFit.contain,
|
|
child: Text(numberSymbol),
|
|
),
|
|
);
|
|
|
|
if (isLandscape) {
|
|
return Flexible(child: button);
|
|
} else {
|
|
return button;
|
|
}
|
|
});
|
|
|
|
if (isLandscape) {
|
|
return Wrap(
|
|
runSpacing: 4.0,
|
|
spacing: 4.0,
|
|
children: numberButtons,
|
|
);
|
|
} else {
|
|
return GridView.count(
|
|
crossAxisCount: blockSize,
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
padding: EdgeInsets.zero,
|
|
mainAxisSpacing: 4,
|
|
crossAxisSpacing: 4,
|
|
children: numberButtons,
|
|
);
|
|
}
|
|
}
|
|
} |