177 lines
4.8 KiB
Dart
177 lines
4.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
const double roomGameDesignWidth = 750;
|
|
|
|
double resolveRoomGameAvailableHeight(
|
|
BuildContext context, {
|
|
double reservedTop = 12,
|
|
}) {
|
|
final mediaQuery = MediaQuery.maybeOf(context);
|
|
if (mediaQuery == null) {
|
|
return 0;
|
|
}
|
|
|
|
final bottomInset =
|
|
mediaQuery.viewInsets.bottom > mediaQuery.padding.bottom
|
|
? mediaQuery.viewInsets.bottom
|
|
: mediaQuery.padding.bottom;
|
|
final availableHeight =
|
|
mediaQuery.size.height -
|
|
mediaQuery.padding.top -
|
|
bottomInset -
|
|
reservedTop;
|
|
if (!availableHeight.isFinite || availableHeight <= 0) {
|
|
return mediaQuery.size.height;
|
|
}
|
|
return availableHeight.clamp(0.0, mediaQuery.size.height).toDouble();
|
|
}
|
|
|
|
double clampRoomGameHeight(
|
|
double value,
|
|
double maxHeight, {
|
|
double minHeight = 0,
|
|
}) {
|
|
if (!value.isFinite || value <= 0) {
|
|
return maxHeight > 0 ? maxHeight : 0;
|
|
}
|
|
if (!maxHeight.isFinite || maxHeight <= 0) {
|
|
return value;
|
|
}
|
|
if (minHeight > maxHeight) {
|
|
return maxHeight;
|
|
}
|
|
return value.clamp(minHeight, maxHeight).toDouble();
|
|
}
|
|
|
|
String resolveRoomGameScreenMode(
|
|
Map<String, dynamic> launchParams, {
|
|
required bool fullScreen,
|
|
}) {
|
|
final candidates = <String>[
|
|
launchParams['screenMode']?.toString() ?? '',
|
|
launchParams['screen_mode']?.toString() ?? '',
|
|
launchParams['displayMode']?.toString() ?? '',
|
|
launchParams['gameScreenMode']?.toString() ?? '',
|
|
];
|
|
for (final candidate in candidates) {
|
|
final trimmed = candidate.trim();
|
|
if (trimmed.isNotEmpty) {
|
|
return trimmed.toLowerCase();
|
|
}
|
|
}
|
|
return fullScreen ? 'full' : 'half';
|
|
}
|
|
|
|
double resolveRoomGameCompatibilityBottomHeight(BuildContext context) {
|
|
final mediaQuery = MediaQuery.maybeOf(context);
|
|
if (mediaQuery == null) {
|
|
return 0;
|
|
}
|
|
final isClassicScreen = mediaQuery.padding.bottom <= 0.5;
|
|
if (!isClassicScreen) {
|
|
return 0;
|
|
}
|
|
|
|
return (mediaQuery.size.width * 0.19).clamp(56.0, 88.0).toDouble();
|
|
}
|
|
|
|
class RoomGameCompatibilityBottomFrame extends StatelessWidget {
|
|
const RoomGameCompatibilityBottomFrame({super.key, required this.height});
|
|
|
|
final double height;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (height <= 0) {
|
|
return const SizedBox.shrink();
|
|
}
|
|
|
|
return SizedBox(
|
|
height: height,
|
|
width: double.infinity,
|
|
child: CustomPaint(painter: _RoomGameBottomFramePainter()),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _RoomGameBottomFramePainter extends CustomPainter {
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final radius = Radius.circular(size.height * 0.18);
|
|
final frameRect = RRect.fromRectAndCorners(
|
|
Offset.zero & size,
|
|
topLeft: radius,
|
|
topRight: radius,
|
|
);
|
|
|
|
final backgroundPaint =
|
|
Paint()
|
|
..shader = const LinearGradient(
|
|
begin: Alignment.topCenter,
|
|
end: Alignment.bottomCenter,
|
|
colors: <Color>[Color(0xFF0E392E), Color(0xFF082A23)],
|
|
).createShader(Offset.zero & size);
|
|
canvas.drawRRect(frameRect, backgroundPaint);
|
|
|
|
canvas.save();
|
|
canvas.clipRRect(frameRect);
|
|
final patternPaint =
|
|
Paint()
|
|
..color = const Color(0xFF2C5B4A).withValues(alpha: 0.20)
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = 1.5;
|
|
final motifWidth = size.width / 8;
|
|
final motifHeight = size.height / 2.4;
|
|
for (double x = -motifWidth; x < size.width + motifWidth; x += motifWidth) {
|
|
for (
|
|
double y = -motifHeight * 0.2;
|
|
y < size.height + motifHeight;
|
|
y += motifHeight * 0.72
|
|
) {
|
|
final rect = Rect.fromCenter(
|
|
center: Offset(x + motifWidth * 0.52, y + motifHeight * 0.55),
|
|
width: motifWidth * 0.9,
|
|
height: motifHeight,
|
|
);
|
|
canvas.drawArc(rect, -0.35, 4.5, false, patternPaint);
|
|
canvas.drawArc(
|
|
rect.translate(motifWidth * 0.34, 0),
|
|
2.75,
|
|
3.6,
|
|
false,
|
|
patternPaint,
|
|
);
|
|
}
|
|
}
|
|
canvas.restore();
|
|
|
|
final borderPaint =
|
|
Paint()
|
|
..color = const Color(0xFFE9D58A)
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = 3;
|
|
final innerBorderPaint =
|
|
Paint()
|
|
..color = const Color(0xFF8F7136).withValues(alpha: 0.75)
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = 1;
|
|
|
|
canvas.drawRRect(frameRect.deflate(1.5), borderPaint);
|
|
canvas.drawRRect(frameRect.deflate(5), innerBorderPaint);
|
|
|
|
final highlightPaint =
|
|
Paint()
|
|
..shader = const LinearGradient(
|
|
colors: <Color>[
|
|
Color(0x00F6E8A7),
|
|
Color(0x99F6E8A7),
|
|
Color(0x00F6E8A7),
|
|
],
|
|
).createShader(Rect.fromLTWH(0, 0, size.width, 3));
|
|
canvas.drawRect(Rect.fromLTWH(0, 0, size.width, 3), highlightPaint);
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
|
}
|