Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import androidx.camera.view.PreviewView
import com.margelo.nitro.NitroModules
import com.margelo.nitro.camera.FocusOptions
import com.margelo.nitro.camera.HybridCameraControllerSpec
import com.margelo.nitro.camera.HybridMeteringPointSpec
import com.margelo.nitro.camera.HybridTapToFocusGestureControllerSpec
import com.margelo.nitro.camera.ListenerSubscription
import com.margelo.nitro.camera.hybrids.HybridCameraController
import com.margelo.nitro.camera.hybrids.metering.HybridMeteringPoint
import com.margelo.nitro.camera.public.NativeGestureController
Expand All @@ -24,8 +26,11 @@ class HybridTapToFocusGestureController :
override var controller: HybridCameraControllerSpec? = null

private var previewView: PreviewView? = null
private val onTapListeners = mutableSetOf<(HybridMeteringPointSpec) -> Unit>()
private val onFocusCompletedListeners = mutableSetOf<(HybridMeteringPointSpec) -> Unit>()
private val context: Context
get() = NitroModules.applicationContext ?: throw Error("Context not available!")
private val mainHandler = Handler(Looper.getMainLooper())
private var isTracking = false
private val gestureDetector =
GestureDetector(
Expand All @@ -42,12 +47,22 @@ class HybridTapToFocusGestureController :
val controller = controller ?: return false

val point = previewView.meteringPointFactory.createPoint(e.x, e.y)
val meteringPoint = HybridMeteringPoint(e.x.toDouble(), e.y.toDouble(), null, point)
controller.focusTo(meteringPoint, FocusOptions(null, null, null, null))
val density = context.resources.displayMetrics.density
val meteringPoint = HybridMeteringPoint((e.x / density).toDouble(), (e.y / density).toDouble(), null, point)
onTapListeners.toList().forEach { it(meteringPoint) }
controller
.focusTo(meteringPoint, FocusOptions(null, null, null, null))
.then {
mainHandler.post {
onFocusCompletedListeners.toList().forEach { it(meteringPoint) }
}
}.catch { error ->
Log.e(TAG, "Failed to focus!", error)
}
return true
}
},
Handler(Looper.getMainLooper()),
mainHandler,
)

override fun onTouchEvent(
Expand Down Expand Up @@ -93,4 +108,18 @@ class HybridTapToFocusGestureController :
}
}
}

override fun addOnTapListener(onTap: (HybridMeteringPointSpec) -> Unit): ListenerSubscription {
onTapListeners.add(onTap)
return ListenerSubscription {
onTapListeners.remove(onTap)
}
}

override fun addOnFocusCompletedListener(onFocusCompleted: (HybridMeteringPointSpec) -> Unit): ListenerSubscription {
onFocusCompletedListeners.add(onFocusCompleted)
return ListenerSubscription {
onFocusCompletedListeners.remove(onFocusCompleted)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ final class HybridTapToFocusGestureController: HybridTapToFocusGestureController
weak var controller: (any HybridCameraControllerSpec)? = nil

private weak var previewView: (any HybridPreviewViewSpec)? = nil
private var onTapListeners: [UUID: (any HybridMeteringPointSpec) -> Void] = [:]
private var onFocusCompletedListeners: [UUID: (any HybridMeteringPointSpec) -> Void] = [:]

override init() {
super.init()
Expand All @@ -34,12 +36,45 @@ final class HybridTapToFocusGestureController: HybridTapToFocusGestureController
viewX: viewPoint.x,
viewY: viewPoint.y,
size: nil)
_ = try controller.focusTo(point: meteringPoint, options: FocusOptions())
let tapListeners = Array(onTapListeners.values)
tapListeners.forEach { $0(meteringPoint) }

try controller.focusTo(point: meteringPoint, options: FocusOptions())
.then { [weak self] _ in
DispatchQueue.main.async { [weak self] in
guard let self else { return }
let focusCompletedListeners = Array(self.onFocusCompletedListeners.values)
focusCompletedListeners.forEach { $0(meteringPoint) }
}
}
.catch { error in
logger.error("Failed to focus! \(error)")
}
} catch {
logger.error("Failed to focus! \(error)")
}
}

func addOnTapListener(onTap: @escaping (any HybridMeteringPointSpec) -> Void)
-> ListenerSubscription
{
let id = UUID()
onTapListeners[id] = onTap
return ListenerSubscription { [weak self] in
self?.onTapListeners.removeValue(forKey: id)
}
}

func addOnFocusCompletedListener(
onFocusCompleted: @escaping (any HybridMeteringPointSpec) -> Void
) -> ListenerSubscription {
let id = UUID()
onFocusCompletedListeners[id] = onFocusCompleted
return ListenerSubscription { [weak self] in
self?.onFocusCompletedListeners.removeValue(forKey: id)
}
}

func onAttached(to preview: any HybridPreviewViewSpec) {
self.previewView = preview
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading