diff --git a/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/gestures/HybridZoomGestureController.kt b/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/gestures/HybridZoomGestureController.kt index b9ce7e7ff5..6b7437df01 100644 --- a/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/gestures/HybridZoomGestureController.kt +++ b/packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/gestures/HybridZoomGestureController.kt @@ -10,6 +10,7 @@ import androidx.camera.core.Camera import com.margelo.nitro.NitroModules import com.margelo.nitro.camera.HybridCameraControllerSpec import com.margelo.nitro.camera.HybridZoomGestureControllerSpec +import com.margelo.nitro.camera.ListenerSubscription import com.margelo.nitro.camera.hybrids.HybridCameraController import com.margelo.nitro.camera.public.NativeGestureController import kotlin.math.max @@ -28,6 +29,7 @@ class HybridZoomGestureController : get() = NitroModules.applicationContext ?: throw Error("Context not available!") private var initialZoomFactor = 1f private var isPinching = false + private val onZoomChangedListeners = mutableSetOf<(Double) -> Unit>() private val camera: Camera? get() { val controller = controller as? HybridCameraController ?: return null @@ -59,6 +61,7 @@ class HybridZoomGestureController : val maxZoom = min(zoomState.maxZoomRatio, MAX_ZOOM_FACTOR) val zoom = min(max(targetFactor, minZoom), maxZoom) + onZoomChangedListeners.toList().forEach { it(zoom.toDouble()) } camera.cameraControl.setZoomRatio(zoom) return super.onScale(detector) } @@ -117,4 +120,11 @@ class HybridZoomGestureController : } } } + + override fun addOnZoomChangedListener(onZoomChanged: (Double) -> Unit): ListenerSubscription { + onZoomChangedListeners.add(onZoomChanged) + return ListenerSubscription { + onZoomChangedListeners.remove(onZoomChanged) + } + } } diff --git a/packages/react-native-vision-camera/ios/Hybrid Objects/Gestures/HybridZoomGestureController.swift b/packages/react-native-vision-camera/ios/Hybrid Objects/Gestures/HybridZoomGestureController.swift index e2f5ab569f..55636812e2 100644 --- a/packages/react-native-vision-camera/ios/Hybrid Objects/Gestures/HybridZoomGestureController.swift +++ b/packages/react-native-vision-camera/ios/Hybrid Objects/Gestures/HybridZoomGestureController.swift @@ -15,6 +15,7 @@ final class HybridZoomGestureController: HybridZoomGestureControllerSpec, Native private let MAX_ZOOM_FACTOR = 15.0 private var initialZoomFactor = 1.0 + private var onZoomChangedListeners: [UUID: (Double) -> Void] = [:] override init() { super.init() @@ -36,6 +37,9 @@ final class HybridZoomGestureController: HybridZoomGestureControllerSpec, Native let minZoom = device.minAvailableVideoZoomFactor let maxZoom = min(device.maxAvailableVideoZoomFactor, MAX_ZOOM_FACTOR) let zoom = min(max(targetFactor, minZoom), maxZoom) + let listeners = Array(onZoomChangedListeners.values) + + listeners.forEach { $0(zoom) } controller.queue.async { do { @@ -50,4 +54,14 @@ final class HybridZoomGestureController: HybridZoomGestureControllerSpec, Native break } } + + func addOnZoomChangedListener(onZoomChanged: @escaping (Double) -> Void) + -> ListenerSubscription + { + let id = UUID() + onZoomChangedListeners[id] = onZoomChanged + return ListenerSubscription { [weak self] in + self?.onZoomChangedListeners.removeValue(forKey: id) + } + } } diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/VisionCameraOnLoad.cpp b/packages/react-native-vision-camera/nitrogen/generated/android/VisionCameraOnLoad.cpp index fcf987e3fb..e160f76018 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/android/VisionCameraOnLoad.cpp +++ b/packages/react-native-vision-camera/nitrogen/generated/android/VisionCameraOnLoad.cpp @@ -25,6 +25,7 @@ #include "JHybridTapToFocusGestureControllerSpec.hpp" #include "JFunc_void_std__shared_ptr_HybridMeteringPointSpec_.hpp" #include "JHybridZoomGestureControllerSpec.hpp" +#include "JFunc_void_double.hpp" #include "JHybridCameraDeviceSpec.hpp" #include "JHybridCameraDeviceFactorySpec.hpp" #include "JFunc_void_std__vector_std__shared_ptr_HybridCameraDeviceSpec__.hpp" @@ -134,6 +135,7 @@ void registerAllNatives() { margelo::nitro::camera::JHybridTapToFocusGestureControllerSpec::CxxPart::registerNatives(); margelo::nitro::camera::JFunc_void_std__shared_ptr_HybridMeteringPointSpec__cxx::registerNatives(); margelo::nitro::camera::JHybridZoomGestureControllerSpec::CxxPart::registerNatives(); + margelo::nitro::camera::JFunc_void_double_cxx::registerNatives(); margelo::nitro::camera::JHybridCameraDeviceSpec::CxxPart::registerNatives(); margelo::nitro::camera::JHybridCameraDeviceFactorySpec::CxxPart::registerNatives(); margelo::nitro::camera::JFunc_void_std__vector_std__shared_ptr_HybridCameraDeviceSpec___cxx::registerNatives(); diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JFunc_void_double.hpp b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JFunc_void_double.hpp new file mode 100644 index 0000000000..fdea4a683e --- /dev/null +++ b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JFunc_void_double.hpp @@ -0,0 +1,75 @@ +/// +/// JFunc_void_double.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include + +#include +#include + +namespace margelo::nitro::camera { + + using namespace facebook; + + /** + * Represents the Java/Kotlin callback `(zoom: Double) -> Unit`. + * This can be passed around between C++ and Java/Kotlin. + */ + struct JFunc_void_double: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/camera/Func_void_double;"; + + public: + /** + * Invokes the function this `JFunc_void_double` instance holds through JNI. + */ + void invoke(double zoom) const { + static const auto method = javaClassStatic()->getMethod("invoke"); + method(self(), zoom); + } + }; + + /** + * An implementation of Func_void_double that is backed by a C++ implementation (using `std::function<...>`) + */ + class JFunc_void_double_cxx final: public jni::HybridClass { + public: + static jni::local_ref fromCpp(const std::function& func) { + return JFunc_void_double_cxx::newObjectCxxArgs(func); + } + + public: + /** + * Invokes the C++ `std::function<...>` this `JFunc_void_double_cxx` instance holds. + */ + void invoke_cxx(double zoom) { + _func(zoom); + } + + public: + [[nodiscard]] + inline const std::function& getFunction() const { + return _func; + } + + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/camera/Func_void_double_cxx;"; + static void registerNatives() { + registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_double_cxx::invoke_cxx)}); + } + + private: + explicit JFunc_void_double_cxx(const std::function& func): _func(func) { } + + private: + friend HybridBase; + std::function _func; + }; + +} // namespace margelo::nitro::camera diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.cpp b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.cpp index 1860a4d434..b80e52e5f6 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.cpp +++ b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.cpp @@ -7,9 +7,17 @@ #include "JHybridZoomGestureControllerSpec.hpp" +// Forward declaration of `ListenerSubscription` to properly resolve imports. +namespace margelo::nitro::camera { struct ListenerSubscription; } // Forward declaration of `HybridCameraControllerSpec` to properly resolve imports. namespace margelo::nitro::camera { class HybridCameraControllerSpec; } +#include "ListenerSubscription.hpp" +#include "JListenerSubscription.hpp" +#include +#include "JFunc_void.hpp" +#include +#include "JFunc_void_double.hpp" #include #include "HybridCameraControllerSpec.hpp" #include @@ -56,6 +64,10 @@ namespace margelo::nitro::camera { } // Methods - + ListenerSubscription JHybridZoomGestureControllerSpec::addOnZoomChangedListener(const std::function& onZoomChanged) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* onZoomChanged */)>("addOnZoomChangedListener_cxx"); + auto __result = method(_javaPart, JFunc_void_double_cxx::fromCpp(onZoomChanged)); + return __result->toCpp(); + } } // namespace margelo::nitro::camera diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.hpp b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.hpp index 74c6cbb980..9d701cafcb 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.hpp +++ b/packages/react-native-vision-camera/nitrogen/generated/android/c++/JHybridZoomGestureControllerSpec.hpp @@ -57,7 +57,7 @@ namespace margelo::nitro::camera { public: // Methods - + ListenerSubscription addOnZoomChangedListener(const std::function& onZoomChanged) override; private: jni::global_ref _javaPart; diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/Func_void_double.kt b/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/Func_void_double.kt new file mode 100644 index 0000000000..96920bddd3 --- /dev/null +++ b/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/Func_void_double.kt @@ -0,0 +1,78 @@ +/// +/// Func_void_double.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.camera + +import androidx.annotation.Keep +import com.facebook.jni.HybridData +import com.facebook.proguard.annotations.DoNotStrip + + +/** + * Represents the JavaScript callback `(zoom: number) => void`. + * This can be either implemented in C++ (in which case it might be a callback coming from JS), + * or in Kotlin/Java (in which case it is a native callback). + */ +@DoNotStrip +@Keep +@Suppress("ClassName", "RedundantUnitReturnType") +fun interface Func_void_double: (Double) -> Unit { + /** + * Call the given JS callback. + * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted. + */ + @DoNotStrip + @Keep + override fun invoke(zoom: Double): Unit +} + +/** + * Represents the JavaScript callback `(zoom: number) => void`. + * This is implemented in C++, via a `std::function<...>`. + * The callback might be coming from JS. + */ +@DoNotStrip +@Keep +@Suppress( + "KotlinJniMissingFunction", "unused", + "RedundantSuppression", "RedundantUnitReturnType", "FunctionName", + "ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName", +) +class Func_void_double_cxx: Func_void_double { + @DoNotStrip + @Keep + private val mHybridData: HybridData + + @DoNotStrip + @Keep + private constructor(hybridData: HybridData) { + mHybridData = hybridData + } + + @DoNotStrip + @Keep + override fun invoke(zoom: Double): Unit + = invoke_cxx(zoom) + + private external fun invoke_cxx(zoom: Double): Unit +} + +/** + * Represents the JavaScript callback `(zoom: number) => void`. + * This is implemented in Java/Kotlin, via a `(Double) -> Unit`. + * The callback is always coming from native. + */ +@DoNotStrip +@Keep +@Suppress("ClassName", "RedundantUnitReturnType", "unused") +class Func_void_double_java(private val function: (Double) -> Unit): Func_void_double { + @DoNotStrip + @Keep + override fun invoke(zoom: Double): Unit { + return this.function(zoom) + } +} diff --git a/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridZoomGestureControllerSpec.kt b/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridZoomGestureControllerSpec.kt index 6f0ef064e2..6ddf623509 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridZoomGestureControllerSpec.kt +++ b/packages/react-native-vision-camera/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/HybridZoomGestureControllerSpec.kt @@ -29,7 +29,14 @@ abstract class HybridZoomGestureControllerSpec: HybridGestureControllerSpec() { // Methods + abstract fun addOnZoomChangedListener(onZoomChanged: (zoom: Double) -> Unit): ListenerSubscription + @DoNotStrip + @Keep + private fun addOnZoomChangedListener_cxx(onZoomChanged: Func_void_double): ListenerSubscription { + val __result = addOnZoomChangedListener(onZoomChanged) + return __result + } // Default implementation of `HybridObject.toString()` override fun toString(): String { diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.cpp b/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.cpp index b4e0b38c79..8d96766346 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.cpp +++ b/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.cpp @@ -474,6 +474,14 @@ namespace margelo::nitro::camera::bridge::swift { }; } + // pragma MARK: std::function + Func_void_double create_Func_void_double(void* NON_NULL swiftClosureWrapper) noexcept { + auto swiftClosure = VisionCamera::Func_void_double::fromUnsafe(swiftClosureWrapper); + return [swiftClosure = std::move(swiftClosure)](double zoom) mutable -> void { + swiftClosure.call(zoom); + }; + } + // pragma MARK: std::function>& /* newDevices */)> Func_void_std__vector_std__shared_ptr_HybridCameraDeviceSpec__ create_Func_void_std__vector_std__shared_ptr_HybridCameraDeviceSpec__(void* NON_NULL swiftClosureWrapper) noexcept { auto swiftClosure = VisionCamera::Func_void_std__vector_std__shared_ptr_HybridCameraDeviceSpec__::fromUnsafe(swiftClosureWrapper); diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp b/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp index 20ea1730da..d88408e9e0 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp +++ b/packages/react-native-vision-camera/nitrogen/generated/ios/VisionCamera-Swift-Cxx-Bridge.hpp @@ -1347,6 +1347,28 @@ namespace margelo::nitro::camera::bridge::swift { return Func_void_std__shared_ptr_HybridMeteringPointSpec__Wrapper(std::move(value)); } + // pragma MARK: std::function + /** + * Specialized version of `std::function`. + */ + using Func_void_double = std::function; + /** + * Wrapper class for a `std::function`, this can be used from Swift. + */ + class Func_void_double_Wrapper final { + public: + explicit Func_void_double_Wrapper(std::function&& func): _function(std::make_unique>(std::move(func))) {} + inline void call(double zoom) const noexcept { + _function->operator()(zoom); + } + private: + std::unique_ptr> _function; + } SWIFT_NONCOPYABLE; + Func_void_double create_Func_void_double(void* NON_NULL swiftClosureWrapper) noexcept; + inline Func_void_double_Wrapper wrap_Func_void_double(Func_void_double value) noexcept { + return Func_void_double_Wrapper(std::move(value)); + } + // pragma MARK: std::vector> /** * Specialized version of `std::vector>`. diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridZoomGestureControllerSpecSwift.hpp b/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridZoomGestureControllerSpecSwift.hpp index 3591dd3a05..5c81902863 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridZoomGestureControllerSpecSwift.hpp +++ b/packages/react-native-vision-camera/nitrogen/generated/ios/c++/HybridZoomGestureControllerSpecSwift.hpp @@ -12,9 +12,13 @@ // Forward declaration of `HybridZoomGestureControllerSpec_cxx` to properly resolve imports. namespace VisionCamera { class HybridZoomGestureControllerSpec_cxx; } +// Forward declaration of `ListenerSubscription` to properly resolve imports. +namespace margelo::nitro::camera { struct ListenerSubscription; } // Forward declaration of `HybridGestureControllerSpecSwift` to properly resolve imports. namespace margelo::nitro::camera { class HybridGestureControllerSpecSwift; } +#include "ListenerSubscription.hpp" +#include #include "HybridGestureControllerSpecSwift.hpp" #include "VisionCamera-Swift-Cxx-Umbrella.hpp" @@ -68,7 +72,14 @@ namespace margelo::nitro::camera { public: // Methods - + inline ListenerSubscription addOnZoomChangedListener(const std::function& onZoomChanged) override { + auto __result = _swiftPart.addOnZoomChangedListener(onZoomChanged); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } private: VisionCamera::HybridZoomGestureControllerSpec_cxx _swiftPart; diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/Func_void_double.swift b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/Func_void_double.swift new file mode 100644 index 0000000000..6b96f4e016 --- /dev/null +++ b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/Func_void_double.swift @@ -0,0 +1,46 @@ +/// +/// Func_void_double.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Wraps a Swift `(_ zoom: Double) -> Void` as a class. + * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`. + */ +public final class Func_void_double { + public typealias bridge = margelo.nitro.camera.bridge.swift + + private let closure: (_ zoom: Double) -> Void + + public init(_ closure: @escaping (_ zoom: Double) -> Void) { + self.closure = closure + } + + @inline(__always) + public func call(zoom: Double) -> Void { + self.closure(zoom) + } + + /** + * Casts this instance to a retained unsafe raw pointer. + * This acquires one additional strong reference on the object! + */ + @inline(__always) + public func toUnsafe() -> UnsafeMutableRawPointer { + return Unmanaged.passRetained(self).toOpaque() + } + + /** + * Casts an unsafe pointer to a `Func_void_double`. + * The pointer has to be a retained opaque `Unmanaged`. + * This removes one strong reference from the object! + */ + @inline(__always) + public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_double { + return Unmanaged.fromOpaque(pointer).takeRetainedValue() + } +} diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec.swift b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec.swift index 938804d35a..0667dbf897 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec.swift +++ b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec.swift @@ -13,7 +13,7 @@ public protocol HybridZoomGestureControllerSpec_protocol: HybridObject, HybridGe // Methods - + func addOnZoomChangedListener(onZoomChanged: @escaping (_ zoom: Double) -> Void) throws -> ListenerSubscription } public extension HybridZoomGestureControllerSpec_protocol { diff --git a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec_cxx.swift b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec_cxx.swift index 61cb9be4c3..b1da9b02ad 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec_cxx.swift +++ b/packages/react-native-vision-camera/nitrogen/generated/ios/swift/HybridZoomGestureControllerSpec_cxx.swift @@ -127,5 +127,20 @@ open class HybridZoomGestureControllerSpec_cxx : HybridGestureControllerSpec_cxx // Methods - + @inline(__always) + public final func addOnZoomChangedListener(onZoomChanged: bridge.Func_void_double) -> bridge.Result_ListenerSubscription_ { + do { + let __result = try self.__implementation.addOnZoomChangedListener(onZoomChanged: { () -> (Double) -> Void in + let __wrappedFunction = bridge.wrap_Func_void_double(onZoomChanged) + return { (__zoom: Double) -> Void in + __wrappedFunction.call(__zoom) + } + }()) + let __resultCpp = __result + return bridge.create_Result_ListenerSubscription_(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_ListenerSubscription_(__exceptionPtr) + } + } } diff --git a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.cpp b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.cpp index f7524b4ae8..02acc4b244 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.cpp +++ b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.cpp @@ -15,7 +15,7 @@ namespace margelo::nitro::camera { HybridGestureControllerSpec::loadHybridMethods(); // load custom methods/properties registerHybrids(this, [](Prototype& prototype) { - + prototype.registerHybridMethod("addOnZoomChangedListener", &HybridZoomGestureControllerSpec::addOnZoomChangedListener); }); } diff --git a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.hpp b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.hpp index 654128cff6..783b459199 100644 --- a/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.hpp +++ b/packages/react-native-vision-camera/nitrogen/generated/shared/c++/HybridZoomGestureControllerSpec.hpp @@ -13,9 +13,13 @@ #error NitroModules cannot be found! Are you sure you installed NitroModules properly? #endif +// Forward declaration of `ListenerSubscription` to properly resolve imports. +namespace margelo::nitro::camera { struct ListenerSubscription; } // Forward declaration of `HybridGestureControllerSpec` to properly resolve imports. namespace margelo::nitro::camera { class HybridGestureControllerSpec; } +#include "ListenerSubscription.hpp" +#include #include #include "HybridGestureControllerSpec.hpp" @@ -50,7 +54,7 @@ namespace margelo::nitro::camera { public: // Methods - + virtual ListenerSubscription addOnZoomChangedListener(const std::function& onZoomChanged) = 0; protected: // Hybrid Setup diff --git a/packages/react-native-vision-camera/src/specs/gestures/ZoomGestureController.nitro.ts b/packages/react-native-vision-camera/src/specs/gestures/ZoomGestureController.nitro.ts index 402e73e4c8..02da8f75c1 100644 --- a/packages/react-native-vision-camera/src/specs/gestures/ZoomGestureController.nitro.ts +++ b/packages/react-native-vision-camera/src/specs/gestures/ZoomGestureController.nitro.ts @@ -1,4 +1,5 @@ import type { CameraController } from '../CameraController.nitro' +import type { ListenerSubscription } from '../common-types/ListenerSubscription' import type { GestureController } from './GestureController.nitro' /** @@ -7,4 +8,16 @@ import type { GestureController } from './GestureController.nitro' * {@linkcode CameraController.zoom | zoom} via a * native pinch-to-zoom gesture. */ -export interface ZoomGestureController extends GestureController {} +export interface ZoomGestureController extends GestureController { + /** + * Adds a listener that is called whenever this native pinch gesture + * changes the target zoom factor. + * + * The listener can be called many times during one pinch gesture. + * Call {@linkcode ListenerSubscription.remove | remove()} on the returned + * subscription to stop receiving updates. + */ + addOnZoomChangedListener( + onZoomChanged: (zoom: number) => void, + ): ListenerSubscription +}