build method

  1. @override
Widget build(
  1. BuildContext context
)

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);
}