build method
Implementation
@override
Widget build(BuildContext context) {
// Check if widget is visible before wasting resources on building it
if (!widget.model.visible) return const Offstage();
// wait for controller to initialize
try {
if (initialized != true ||
(controller == null) ||
(!controller!.value.isInitialized)) {
return Container();
}
} catch (e) {
return Container();
}
//////////
/* View */
//////////
Widget view;
_pointers = 0;
// camera
view = CameraPreview(controller!, child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onScaleStart: _handleScaleStart,
onScaleUpdate: _handleScaleUpdate,
onTapDown: (TapDownDetails details) =>
onViewFinderTap(details, constraints),
);
}));
// camera
view = Listener(
onPointerDown: (_) => _pointers++,
onPointerUp: (_) => _pointers--,
child: view);
//////////////////
/* Constrained? */
//////////////////
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
// basic constraints
view = SizedBox(width: width, height: height, child: view);
// apply user defined constraints
view = applyConstraints(view, widget.model.constraints);
// stack children
List<Widget> children = [];
children.add(view);
// hack to initialize background camera stream. current camera widget doesn't support streaming in web
if ((FmlEngine.isWeb) &&
(widget.model.stream) &&
(backgroundStream == null)) {
backgroundStream = StreamView(widget.model);
if (backgroundStream != null) {
children.add(Offstage(child: backgroundStream as Widget?));
}
}
// build the child views
children.addAll(widget.model.inflate());
// show controls
if (widget.model.controls != false) {
// zoom slider
Slider? zoomslider;
if (_maxAvailableZoom > _minAvailableZoom) {
zoomslider = Slider(
value: _zoom,
min: _minAvailableZoom,
max: _maxAvailableZoom,
activeColor: Colors.white,
inactiveColor: Colors.white30,
onChanged: (value) async {
setState(() {
_zoom = value;
});
await controller!.setZoomLevel(value);
});
children
.add(Positioned(bottom: -10, left: 0, right: 0, child: zoomslider));
}
// camera selector
Widget selector;
if (cameras != null && cameras!.length > 1) {
selectorbutton ??= IconView(IconModel(null, null,
icon: Icons.cameraswitch_sharp, size: 25, color: Colors.black));
selector = UnconstrainedBox(
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: toggleCamera,
child: Stack(alignment: Alignment.center, children: [
const Icon(Icons.circle, color: Colors.white38, size: 65),
const Icon(Icons.circle, color: Colors.white38, size: 50),
selectorbutton!
]))));
children.add(Positioned(bottom: 25, left: 10, child: selector));
}
// shutter
shutterbutton ??= IconView(IconModel(null, null,
icon: Icons.circle, size: 65, color: Colors.white));
var shutter = UnconstrainedBox(
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: snapshot,
child: Stack(alignment: Alignment.center, children: [
const Icon(Icons.circle, color: Colors.white38, size: 80),
shutterbutton!
]))));
children.add(Positioned(bottom: 25, left: 0, right: 0, child: shutter));
}
// final view
return Stack(children: children);
}