ponshu-room-lite/lib/widgets/map/pixel_japan_map.dart

88 lines
2.7 KiB
Dart

import 'package:flutter/material.dart';
import '../../models/maps/japan_map_data.dart';
import '../../theme/app_theme.dart';
class PixelJapanMap extends StatelessWidget {
final Set<String> visitedPrefectures;
final Function(String prefecture)? onPrefectureTap;
const PixelJapanMap({
super.key,
required this.visitedPrefectures,
this.onPrefectureTap,
});
@override
Widget build(BuildContext context) {
// Determine grid dimensions
final rows = JapanMapData.gridLayout.length;
final cols = JapanMapData.gridLayout[0].length;
// Fixed base cell size for drawing - FittedBox will scale it to screen
// Increased to 32.0 for better touch targets (Hit Box), visual size will be smaller
const double touchSize = 32.0;
const double visualSize = 22.0; // Slightly larger for visibility
const double gap = 0.0; // Gap is now handled by padding inside cell
final totalWidth = cols * (touchSize + gap);
final totalHeight = rows * (touchSize + gap);
return SizedBox(
width: totalWidth,
height: totalHeight,
child: Column(
children: JapanMapData.gridLayout.map((row) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: row.map((prefId) {
return _buildCell(context, prefId, touchSize, visualSize);
}).toList(),
);
}).toList(),
),
);
}
Widget _buildCell(BuildContext context, int prefId, double touchSize, double visualSize) {
if (prefId == 0) {
return SizedBox(width: touchSize, height: touchSize);
}
final prefName = JapanMapData.prefectureNames[prefId] ?? '';
final isVisited = visitedPrefectures.any((p) => p.startsWith(prefName.replaceAll(RegExp(r'[都道府県]'), '')));
Color color;
if (isVisited) {
color = AppTheme.posimaiBlue;
} else {
final regionId = JapanMapData.getRegionId(prefId);
color = (regionId % 2 == 0) ? Colors.grey[200]! : Colors.grey[300]!;
}
return GestureDetector(
behavior: HitTestBehavior.opaque, // Ensure touches on transparent padding are caught
onTap: () {
if (prefName.isNotEmpty && onPrefectureTap != null) {
onPrefectureTap!(prefName);
}
},
child: Container(
width: touchSize,
height: touchSize,
alignment: Alignment.center,
child: Tooltip(
message: prefName,
child: Container(
width: visualSize,
height: visualSize,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(visualSize * 0.15),
),
),
),
),
);
}
}