You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.6 KiB
110 lines
2.6 KiB
// SPDX-FileCopyrightText: Copyright 2023 Open Mobile Platform LLC <community@omp.ru> |
|
// SPDX-License-Identifier: BSD-3-Clause |
|
import 'package:camera_aurora/camera_aurora_platform_interface.dart'; |
|
import 'package:flutter/material.dart'; |
|
|
|
import 'camera_data.dart'; |
|
|
|
class CameraViewfinder extends StatefulWidget { |
|
const CameraViewfinder({ |
|
super.key, |
|
required this.width, |
|
required this.height, |
|
}); |
|
|
|
final double width; |
|
final double height; |
|
|
|
@override |
|
State<CameraViewfinder> createState() => _CameraViewfinderState(); |
|
} |
|
|
|
class _CameraViewfinderState extends State<CameraViewfinder> { |
|
CameraState _cameraState = CameraState.fromJson({}); |
|
|
|
@override |
|
initState() { |
|
super.initState(); |
|
CameraAuroraPlatform.instance.startCapture(widget.width, widget.height); |
|
CameraAuroraPlatform.instance.onChangeState().listen((event) { |
|
if (mounted) { |
|
setState(() { |
|
_cameraState = event; |
|
}); |
|
} |
|
}); |
|
} |
|
|
|
@override |
|
void dispose() { |
|
CameraAuroraPlatform.instance.stopCapture(); |
|
super.dispose(); |
|
} |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
if (_cameraState.hasError()) { |
|
return Center( |
|
child: Text( |
|
'Error: ${_cameraState.error}', |
|
style: |
|
const TextStyle(fontWeight: FontWeight.bold, color: Colors.white), |
|
), |
|
); |
|
} else if (_cameraState.isNotEmpty()) { |
|
int turn = 0; |
|
|
|
// @todo Different direction of rotation |
|
bool isFront = _cameraState.id.contains('front'); |
|
|
|
switch (_cameraState.mountAngle) { |
|
case 0: |
|
turn += 0; |
|
break; |
|
case 90: |
|
turn += 1; |
|
break; |
|
case 180: |
|
turn += 2; |
|
break; |
|
default: // 270 |
|
turn += 3; |
|
} |
|
|
|
switch (_cameraState.rotationDisplay) { |
|
case 0: |
|
turn += 0; |
|
break; |
|
case 90: |
|
turn += isFront ? 1 : -1; |
|
break; |
|
case 180: |
|
turn += 2; |
|
break; |
|
default: // 270 |
|
turn += isFront ? 3 : -3; |
|
} |
|
|
|
double cw = turn % 2 == 0 ? _cameraState.height : _cameraState.width; |
|
double ch = turn % 2 == 0 ? _cameraState.width : _cameraState.height; |
|
|
|
double height = widget.height; |
|
double width = widget.height * cw / ch; |
|
|
|
if (width > widget.width) { |
|
width = widget.width; |
|
height = widget.width * ch / cw; |
|
} |
|
|
|
return SizedBox( |
|
width: width, |
|
height: height, |
|
child: RotatedBox( |
|
quarterTurns: turn, |
|
child: Texture(textureId: _cameraState.textureId), |
|
), |
|
); |
|
} |
|
return const SizedBox.shrink(); |
|
} |
|
}
|
|
|